Thymeleaf: Reducing White Space
A working project with Java and Spring Boot
As a techie geek I sometimes look at the source for web pages to see how things work and it surprised me how much white space there was. White space adds nothing to the experience and offers no benefit to the viewer but so much is sent to the browser. Modern tech hides bloat and my own site EVEMissioneer (link at the end) was especially bad at churning out white space.
There are some snippets of code on the web about how to reduce white space for HTML content. A 2021 post by Yamani Rodriguez related to Thymeleaf looked good (link at the end) but it was only the extension part so I built this beginning-to-end example to prove and demonstrate how white space can be removed. The extension is live on my site.
The example project lives here: https://github.com/robincakeellis/thymeleafwhitespace
Executive Summary
I want a working Java project that uses Spring Boot and Thymeleaf to return compact HTML content. The project must have build-time tests.
Why Bother About White Space?
Modern browsers can handle large web content, and server compression keeps the delivery size low. However, extraneous white space is data that uses memory when decompressed and the white space is padding that the browser needs to skip.
Another issue with white space is that the server needs to use more memory when building a page. White space can easily creep in for dynamic content when using loops for a series of divs, for choices in a list selector or for rows in a table.
Thymeleaf can be extended with relatively few lines of code so that white space is not written. The server uses less memory to build the page; GZip has less to compress; and the browser needs less memory to decompress and show the content. These savings may be small but one way to make big savings is to have lots of small ones.
Some white space may be essential — in a paragraph for example — and that space is retained. The extraneous white space between tags and the irrelevant new-line characters are removed.
Tech Stack
- Java: OpenJDK 17
- Spring Boot: 3.0.6
- Thymeleaf: 3.1.1
- Junit: version 5
- Apache Maven: any modern version should be fine
Project Structure
A standard Spring Boot app with:
- a POM
- an annotated class that serves as the entry point plus some config for the Thymeleaf extension
- a controller with a response DTO
- two classes that implement the Thymeleaf extension
- a unit test to check application can start
- two unit tests to check the controller response
The resources are:
- properties to set up the server, and to allow testing
- a static folder containing a CSS file
- a templates folder containing a simple Thymeleaf template called
index.html
— note the white space in this file as most of it will be removed
Adding The Extension
The extension is added using an @Bean
in the main app. We apply the default resolver — available as an auto-wired property — and add the extension to the engine so Spring will have what it needs to return HTML content.
This app uses a property to include the extension (or not) to support testing.
Viewing The Content
Build and run the app then view the simple page at localhost:8080
. If you look at the source you will see the white space from the template HTML has mostly been removed. The paragraph white space is retained but header elements are joined together. Note also the li
list options are compact.
You can set the application property app.whitespace-remove
to false
, rebuild and run again. Now the white space will match the source template. Note there is a blank line after the h1
due to the conditional paragraph logic and there is white space for every li
list option.
Testing
There are two unit test classes that will prove how white space is treated. I would have preferred one class with two test methods but the @TestPropertySource
annotation (which sets the required runtime property) is class level so the simplest approach is separate classes.
My HTML template is formatted with tabs instead of spaces so one of the tests will look specifically for \t
.
Older Spring Boot Apps
Version 2.x of Spring Boot uses Spring Framework 5 so if you use that you must do two things:
- change the
org.thymeleaf
dependency in the POM fromthymeleaf-spring6
tothymeleaf-spring5
- change the main app import from
org.thymeleaf.spring6.SpringTemplateEngine
to spring5
Review Your Content!
Compressing white space may lead to small layout issues. For example, if you have two buttons on separate lines of your source then there may be a small gap between the buttons when viewed in a browser. This white space extension will remove any white space between the buttons and the visible gap will disappear. CSS can help - or generous use of
(I can hear designers scream …)
Filter As An Alternative
It is possible to use a Filter
as a post processor to compress page content after Spring has built it and before it is returned to the browser. The plus side is it works with any rendering engine (Thymeleaf, FreeMarker, JSP).
I tried this approach in an old release of my site but noticed some downsides. The filter has to wait for a page to be built and then create a copy of it that has the white space removed. This adds pressure on the garbage collector and adds load on the CPU for every HTML page.
We can avoid the Filter approach using Thymeleaf with the post processor extension.
Summary
White space removal is straight forward with Thymeleaf with small benefits to the server and client browser. White space removal is unlikely to be a priority but it is simple to implement and reduces response bloat.
Links
Thymeleaf: https://www.thymeleaf.org/
Handler and processor posted by Yamani Rodriguez: https://github.com/thymeleaf/thymeleaf/issues/108#issuecomment-761724887
Filter as an alternative: https://stackoverflow.com/a/57282059
If you play EVE Online, an agent explorer: https://evemissioneer.com
If you do not play EVE Online: https://www.eveonline.com/