How to load web fonts for the best page load performance

Matt Claffey
4 min readApr 25, 2020

--

Fonts have the potential to be extremely slow. The more you include the more it can impact multiple metrics such as page weight, page load, first paint and first contentful paint.

What performance issues can occur?

Chain requests

A chain request is when a resource that is required by another file instead of the document. When you add font-face inside a css file it will have a dependency on the css file to load before it can load the font in the browser. This can be a problem especially on slow connections because the HTML could take a second to load, then a second for your CSS and then an extra 1–2 seconds for the fonts to load. That is a total of 4 seconds where the user has not seen any text.

When the fonts are slow you can tell all of a sudden seeing no text and then a “blink” and they all appear in the browser. Which is known as FOIT (flash of invisible text).

What is FOIT

Flash of invisible text is when the text on a website is invisible and then when the fonts have loaded they appear on the page. The text is rendered on the page ready but the browser does not know what font to use until they have loaded. When loaded, the the browser will “re-paint” the screen and show the new font, see how FOIT works (does contain flashing images).

We want to remove this “blink” effect and try to have some form of content there so the user can get a feel for what message the website is trying to send quicker than having to wait for the font to load. This is called FOUT (Flash of un-styled text).

What is FOUT

Flash of un-styled text is a popular concept where the user will see the fallback font before seeing the main font that we load in. When implemented we no longer see the invisible font. See how this would work here (does contain flashing images).

Implementing FOUT on your website

So the easiest and quickest way on implementing FOUT is by using a css property called font-display. Font display is added to the font-face and it tells the browser what to do with the font when it is loading. You have a few values that you can have on this property but the main ones we want to do are:

  • swap — forces the browser to swap the font families out

Now let’s see what that would look like in our code:

Extra bonus points!

That is amazing we now get fonts in a little faster but if you are like me and want to make it blazingly fast lets dive deeper into what we can do. The way the fonts load is still the same. As mentioned above we have a chain request where the fonts are dependant on the css loading before it can load itself. Lets sort that out…

Embedding CSS

First thing we can do is embed our font-face css in the html document. Downside to this is not being able to cache the embed code but if your fonts are about 10–30 lines of css then it is not a massive problem.

Example:

Now what will happen is that the font will load regardless of the css. When the css has loaded, if the font has loaded by then it will swap the font font out faster.

Resource hints

The next thing we can do is use a resource hint called “preload”. Preloading a font will tell the network that this font wants to be loaded before anything else. The network will then treat the font as a critical resource and prioritise it when loading assets. Preloading is your friend, but preloading everything has the opposite effect and can make the site load normal again so make sure you prioritise which fonts you want to load. A good starting point is headings and body copy.

For example:

Preload is awesome to use on more than just fonts, the browser support is pretty good it is just ie 11 and Firefox that do not support the feature. Firefox does have this feature if you enable the feature under a flag in dev tools see more on CanIUse.

Hidden gems

Local property

This is a gamer changer! Especially if you are using fonts such as Helvetica on your website. On apple devices Helvetica is installed locally so when the user comes to your website you can tell your css to pick the local font over the one on your server. How neat right?

For example:

Note: make sure you add local first because the order is important on the src property.

Conclusion

So we have learnt about fixing critical requests in the browser, how to implement FOUT and how to add extra hidden gems to make your fonts load blazingly fast!

--

--

Matt Claffey
Matt Claffey

Written by Matt Claffey

Advocate for Site Speed, PWA’s and Accessibility and UI Libraries