Nailing UX with fast font delivery
By: Rogier Slag
Tags: Fonts, UI, Google Web Fonts, UX

Let’s face it: the Internet is all about text. There. I said it. Textual content is still the foundation of the Internet. However little thought seems to be given to actual text delivery. As a developer you just put it in the DOM, and it appears on a users screen right?

Wrong.

Still too many developers, but also other disciplines as UI/UX design, get this wrong. In this blog we’ll take a look at this issue, and how you can make your web fonts blazingly fast!

Adding text can slow everything down

Wait, are you serious? That thingy from 1455 is actually slowing my site down?

If you are not careful, yes. A lot of effort nowadays is put into optimizing Javascript, techniques as lazy-loading or bundle splitting, and lots of other things. But simple content based around text is often forgotten.

Erroneously as it turns out.

While in the absolute basics text could render instantly in your browser, there often are a number of constraints. Quite regularly this resolves around using a specific font (or typeface actually). This can be done for legibility, brand purposes , or for other reasons. No wonder, as nobody wants to be looking at Comic Sans MS all day long.

Sadly this often means a web font is used naively.

What is a web font?

As Mozilla tells us, a web fonts are a CSS feature which allow you to use a hosted font to render text anywhere on your page. And even IE6 does support it!

However, not all browsers accept the same file formats to represent a font. That means that you will need to have different font files for each font, just to ensure a consistent reading experience for your visitors.

As this if often too cumbersome, many will (justly!) use a hosted font service. The most well known example is Google Fonts, which offers a delightful collection of fonts. Even better, each of these are free to use. One could call it designer heaven.

The potential downsides of a hosted service

Having a service handling the different font formats (and much more, like Unicode ranges, and supplying the correct font variants, among others) seems ideal. Some caveats do apply though!

First of all, you are using an additional CSS resource. One additional CSS resource, hoe much can that hurt?!

As you may know, CSS blocks the entire DOM from rendering. So while that request for your font is in progress, absolutely nothing will be visible for your users (effectively a blank page). More experienced developers may recognize this as an increase in Time to Meaningful Paint, one of the metrics used to define the speed of a page in tools as Lighthouse.

Hence if your external CSS file for your font is loading slowly, your entire page will suffer. You might even experience a FOUT or FOIT (respectively a flash of unstyled text or a flash of invisible text).

Secondly, it turns out more and more proxies have started to block access to resources as Google Fonts. Some network administrators want to reduce their users exposure to Google, but at the same time it may mean that your content will render very very differently for these users. Some browsers may even wait indefinitely for the font to become available, in effect giving your users no text indefinitely.

HTTP2 to the rescue!

What is HTTP2 and how can it help?

HTTP2 is the improved version of HTTP1.1 (which in turn was an improved version of HTTP1). HTTP2 improved the performance of HTTP1.1, but also added a still underused option: HTTP2 Server Push. Using this technology a web master can push resources through the already established connection to the client, before the client has even requested them. This can remove the blocking factor that is a CSS stylesheet, making your site appear on your visitors screen much faster!

Some resources are great candidates to push. Among other as CSS, fonts are a great resource to be pushed to the client. Especially with Google Fonts, we will know in advance the exact Google Font URL (as it is in the delivered HTML), so we can remove the delay caused by fetching CSS resources. Instead, we just push the content of that resource along with the requested HTML!

However HTTP2 does not allow you to push resources which are not part of your own domain. So unless you happen to own Google, you’ll have a hard time pushing its contents.

Another trick is needed. More specifically, you need to ensure the CSS and (optionally) font files are served through your domain.

“Fixing” it the easy way

The easiest way is to “just” download all font variations, and just serve them from your application server. Guides for this are available online. However it may not be the best solution:

You need to ensure the correct browsers are getting the correct fonts, Your are missing out on the browser specific improvements Google has made over the years, Improvement in the coming years need to be back-ported manually.

In short, it is a road to an increasing amount of work.

All the above need to be done, checked, and re-done in the future, just to be “your own Google Fonts”. If only there was a way to make that happen!

Enter the proxy

In short our requirement is easy: we want to be exactly Google Fonts, but with our own domain, eg www.yourdomain.com/fonts . This way we benefit from having an already established connection, and potentially HTTP2 server push. Plus we do not have to deal with any maintenance, and get upgrades from Google for free.

All we then need to do is run that proxy! You can pick one directly from my Github: font-cacher. It is implemented as an exact proxy, with some smart caching:

Upon receiving a request for a CSS file, it checks its local cache whether it has a CSS file for exactly that browser and request available. If yes, serve it directly. If not, forward the request to Google and return that response. Also copy the response in the cache to speed up future requests. When sending a CSS response, also add preload headers for the most likely required font files on the requested CSS, to further improve font performance. When receiving a font file request, the action is slightly different. As the file names are unique anyhow, no caching based on the browser is required. The file is just requested from Google Fonts (if not in cache) and served directly. The API is exactly identical to the Google Fonts API. Just substitute the domain and the path, and profit :)

See the entire README.md for more options.

This tackles the downsides we experienced before. The CSS and font files are pushed to the browser before it realized it would need them. That in turn eliminates the blocking phase of the paint. The end result can be a UX delight: a fast website, no flashes of content, and branded exactly the way you want it!

Note: in case your user is geographically far away from your server, using the font files from Google itself could still be beneficial.

Recap

What did we discuss?