We’ve used a custom version of the New Transport font since the launch of GOV.UK. New Transport was rendered on-screen by Base64 encoding font files into a CSS file. Base64 encoding was the preferred technique when we launched in 2012 as it helped to reduce the number of HTTP requests and minimise the flash of unstyled content (FOUC).
Why we changed font loading on GOV.UK
Browsers have improved a lot since 2012 and Base64 encoding font files is now considered a method you should avoid. The main problems we had with the Base64 encoding method were that we:
- forced browsers to download fonts even if they were not used
- could only use the Web Open Font Format (WOFF) because of the file size restriction
Base64 encoding also added extra bytes to the page that were sitting on the browsers’ critical rendering path. All these bytes needed to be loaded before the page could be rendered. The CSS file was approximately 200 kilobytes (KB), which was 82% of the total blocking assets needed to load the page.
How we changed font loading on GOV.UK
We made a simple code change but the impact on the wider GOV.UK codebase was significant. We changed the way the `@font-face` loading method referenced fonts. By removing the inline Base64 encoded font and loading the files via standard HTTP requests we can now:
- serve multiple font types from the same `@font-face` declaration, which allows a browser to choose the appropriate font it supports
- remove approximately 200KB from the critical path to load pages faster
- start to take advantage of modern browser optimisation techniques like the CSS font-display property and resource preloading
The main advantages for end users
Less data usage
Removing the Base64 encoded font has reduced the total page weight by 16% (75 KB) per request (assuming no caching). This may not sound like a huge difference, but GOV.UK receives approximately 48 million visitors per month, so this adds up to mobile users saving approximately 800 GB per month, cumulatively. This is especially important to users on older mobile devices and expensive data plans.
By removing the Base64 encoding we are also giving mobile users the ability to opt in or out of downloading the font completely. This can help users reduce their data consumption.
Faster page loading
We have seen big improvements in page load time since we introduced the change. In our testing, the page load time for high-end devices using 4G dropped by 13% and visual population of the page (Speed Index) reduced by 50%.
But where the change is most noticeable is on slow mobile devices on a 2G connection. Under these conditions the page loads approximately 10 seconds faster according to our simulated SpeedCurve tests. This large performance increase comes in part from the 16% reduction in overall page size, but also from the fact we have removed around 200 KB of CSS that no longer needs to be processed by the browser before the page is shown.
Lower battery power usage
With over 44% of GOV.UK users accessing the website through a mobile device, pages need to render quickly and efficiently. Mobile devices are often CPU, memory and battery limited.
A page with a large amount of blocking data can have a huge impact on users with pre-2012 devices. A GOV.UK page will take longer to download due to the mobile connection speed. The CPU and RAM requirement will increase when processing the data and display content to the screen. These both have an impact on a users mobile battery life. The same principle applies to users on older desktop and laptop devices.
By optimising the GOV.UK frontend code, we are improving the experience for all users no matter what device they are using to access it.
Continuing to improve GOV.UK frontend performance
This is just the first stage in improving the GOV.UK frontend performance. The font foundry is working on a new font that promises to reduce the font weight by another 47% for WOFF2 (50% for WOFF).
We’ll also experiment with new browsers features like the `font-display` property and asset preloading. By combining all these changes we’ll aim to reduce the load time and also the overall page weight for GOV.UK users. This will provide a better user experience for all users no matter how they access the site.
If this sounds like a good place to work, take a look at Working for GDS - we're usually in search of talented people to come and join the team.
4 comments
Comment by Dave posted on
This sounds great — nice to have performance of the page put first & foremost in terms of user's needs, as I think it's definitely the most import aspect in user experience, particularly from mobile.
I think another nice thing about switching back to regular fonts is that it puts the user back in control too — my mobile browser allows me to disable web-font downloads by default, which is very useful when on a mobile data plan & especially when roaming.
Comment by Victor posted on
Hi Matt!
Thank you for your work and efforts to make the Web better.
I’m trying to figure out why there’s such a huge difference between the data URI solution and regular files. Therefore, I would like to know if you had enabled gzip for CSS files, or maybe you can share your test environment.
I’m asking, because I did a few tests and on the contrary, I got better results. If you are interested, compare the following reports:
- 3G Mobile (https://gtmetrix.com/compare/Shy4VZst/3diipG02)
- 2G Mobile (https://gtmetrix.com/compare/P0TZepvZ/OOkf5Sv7)
As you can see, the data URI solution is faster in both cases. If I’m missing something, please let me know.
Best regards,
Victor
Comment by Matt Hobbs posted on
Hi Victor,
Thanks for your reply. So for this simple test case I agree the data version looks like a better option. It performs well because an additional request isn't required for the font file. The font is already baked into the CSS ready to be parsed and displayed without any flash of invisible text (FOIT). With the file version the font request can only be made once both the HTML and the CSS has been parsed. Here's a comparison I made on Web Page Test that really illustrates that point
What you should consider though is what happens when you have a user with a browser that doesn't support WOFF2? Maybe they are on a browser that only supports WOFF, an old version of Firefox or Safari on iOS for example. So you have 2 options. Either these users don't get your custom webfont, or you Base64 encode the WOFF version into your CSS as well. This will work, but what you have essentially done is make every user download both the WOFF and the WOFF2 version of the font (they sit in the same CSS file after all). More bytes have been added to the browsers critical rendering path. Remember nothing can be shown in the viewport until the CSS has been both downloaded and parsed.
Taking it one step further. What about if you have users that don't support WOFF or WOFF2? Older versions of IE are in this position. What you need to do in this case is start to include a separate EOT file to support these browsers. You can't use Data URIs in this case because there are browser limitations in old IE. And why would you want to, you'd then be in the position where all users would have to download an EOT, WOFF, and WOFF2 in a CSS file for your custom font. More bytes in the browsers critical path. So this EOT file will needed to be included separately
Essentially what I'm saying is that the Data URI method doesn't scale well. By splitting out the different font types into their separate requests you are giving the browser the ability to optimise how and when these assets are downloaded. The browser will find the most appropriate font it supports and only download that, ignoring all others.
Another aspect to consider is WOFF2 files are already highly compressed. They perform around 30% better than the original WOFF format. We were using Gzip compression on the resulting CSS files, but this still left a large amount of data (around 200KB) sitting on the browser critical path. That much CSS takes a significant amount of time both to download and to parse.
The final point to consider is caching. For this simple example it isn't really a problem as there's very little happening on the page. But imagine you have your font file Base64 encoded into a big CSS file that controls a large number of pages. Suddenly you need to make a small change to one CSS property on a page. Because of this change the whole CSS file (including the font) will now look like a brand new CSS file to the browser. It will need to be cached again by the user. By separating out the font files from the CSS, that simple change will only effect the core CSS. The font files remain unchanged and cached appropriately.
I highly recommend reading the "Base64 Encoding & Performance" series by Harry Roberts (https://csswizardry.com/2017/02/base64-encoding-and-performance/). He goes into this area of performance in much more detail.
Hope that helps,
Matt
Comment by Victor posted on
Hey! Dear Matt,
Thank you very much for a such detailed reply. Despite the fact that I know some disadvantages of the data URI (e.g., https://base64.guru/developers/data-uri), your helpful comment greatly expanded my knowledge and helped me to understand where I was wrong. I hope you do not mind if I use your thoughts to supplement my article.
As for csswizardry, I doubt about the accuracy of the information, at least because I got different results for his tests. For example, check filmstrips here: https://gtmetrix.com/compare/SUpr6nm4/eGipTpSJ (data URI page is already displayed at 6.5 seconds, while regular image at 14 seconds). Of course, I admit that I may be wrong again, but I am very glad that I decided to ask you and get a wonderful answer.
Thank you once again for everything.
Wishing you a magical Christmas,
Victor