When it comes to making a site faster, if CSS can be overlooked, fonts can be flat out punched in the face. That is, not only do people ignore the impact of fonts on site speed, sometimes the implementation is just plain backwards… on purpose. We’ll try to straighten out that mess, and look at a few other tips for making sure your fonts are speedy, as well as helping your site provide a good user experience.

How About Using System Fonts?

We’re going to start with that last one, because every so often I run across someone saying, “Forget web fonts, just use system fonts!” Which would make this all a moot point, and we can all just use the same few proprietary fonts (Arial, Times New Roman, Verdana, and a couple others). On behalf of all the Linux/UNIX/BSD users in the world, please don’t. There are more than you think, like all the devices running ChromeOS, and Linux-based handhelds like the Steam Deck. So, if you want your site layout to look correct on all devices, just use web fonts and keep reading.

IF, however, you’re willing to put in the time to make sure your layout works across multiple operating systems, then sure, go ahead and use system fonts. Personally, I’ve got better things to do, and I don’t miss fighting layout issues one bit! Ironically, some of those who have advocated system fonts are now back to using a mix of Google Fonts and self-hosted web fonts, but I won’t name names… No really, I won’t!

Making Fonts Smaller

When we look at images, JS, and CSS, a big focus is on compression. But you can’t compress fonts, right? Right?? Or can you? Why yes, you certainly can, and that’s exactly what the WOFF (Web Open Font Format) does. It’s effectively a compression wrapper for TrueType and OpenType fonts, and it’s supported on all modern browsers, and even some very ancient ones. You don’t generally need to compress your fonts though, if you’re using web fonts from a reliable source, WOFF and WOFF2 resources should be provided by default. If not, you really should get your fonts upgraded to WOFF!

Besides that, there’s another way to make your fonts dramatically smaller, and that’s called subsetting. Most web fonts are designed to support a huge range of UTF8 characters, and there are over a million of those! Whatever language you’re writing in, you are likely not using more than a hundred of them (unless you’re Chinese, and maybe not even then). Subsetting splits up a web font into smaller chunks, each with a range of characters, so that only the necessary subsets for your site are loaded. This can be a bit complicated, and is often handled by your font provider, like Google Fonts or Adobe Fonts.

What Could Go Wrong?

So, about that backwards punch-in-the-face, presenting the elephant that is… Google Fonts. To be clear, I think Google Fonts are great, but the implementation leaves a bit to be desired. Let’s break it down then, and see how web fonts generally load, and specifically how Google does it worse than some.

Google Fonts - Inter

The first thing that has to happen to load a font is that the browser needs the CSS file containing the @font-face declarations for your fonts. This is referenced in your HTML, and may be in your theme CSS, but most often it’s loaded directly from Google using a URL like https://fonts.googleapi.com/css2?family=Inter. To get that CSS file, the browser first needs to find the server for fonts.googleapi.com via DNS, and then connect to it over HTTPS. That seems perfectly normal, right?

Then, your browser will have a bunch of code that looks like so:

/* latin-ext */
@font-face {
  font-family: 'Lato';
  font-style: normal;
  font-weight: 400;
  src: url(https://font.gstatic.com/s/inter/v24/S6uyw4BMUTPHjxAwXiWtFCfQ7A.woff2) format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
/* latin */
@font-face {
  font-family: 'Lato';
  font-style: normal;
  font-weight: 400;
  src: url(https://font.gstatic.com/s/inter/v24/S6uyw4BMUTPHjx4wXiWtFCc.woff2) format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

The important thing to note is the font URLs. They come from a different domain, so once your browser does all the work to get your CSS, and then parses your CSS, it finds out it needs to download a font (or two or three) from font.gstatic.com. Guess what? It needs to do the same thing it did for the CSS, lookup the server via DNS, and then connect over HTTPS. And then (finally!) the browser can download the font, and render the text on your page. All this time, your text may be invisible to the user. Nice, huh?

The Less Bad News

To be fair to Google, they’ve improved their embed code in a couple ways, but if your fonts were setup before these changes, then you’re kind of stuck. Well, maybe not, but we’ll get to that in a minute. What about those improvements then?

Display Swap

This is your first best friend when using web fonts, and you should just use it. Google uses the display=swap parameter in font URLs to enable this behavior, which adds font-display: swap to the font CSS. Instead of the above URL, you’ll end up with something like https://fonts.googleapi.com/css2?family=Inter&display=swap. Yes, this means your site will temporarily be rendered in a system font, but at least it won’t be invisible!

Preconnect

The second improvement Google recommends is to add a preconnect directive for the aforementioned domains: fonts.googleapis.com and fonts.gstatic.com. This tells the browser right away that it will need to download resources from those two domains, so that hopefully by the time it tries to download the CSS and font(s), an HTTPS connection will already be established. On desktop, this may not make a huge difference, but it should speed things up for mobile.

Privacy and Font Caching

Well, that seems pretty good, yeah? Maybe not… In this day and age, user privacy is kind of a big deal, and loading all your fonts from Google isn’t great for that. If you want to respect the privacy of your users then, you might look into self-hosting those lovely fonts from Google.

But wait a second, don’t our visitors benefit from caching because of all the thousands of sites that use Google Fonts? Once upon a time, when a visitor’s browser downloaded a font from Google, they would have it available for any other site. So unless your visitors were just recently living in caves, you had a good chance that your fonts were already cached in your visitor’s browser. Unfortunately, caching fonts across different domains is a security risk, so browsers only cache fonts for a single domain/site, and now you might as well host your own fonts.

What to do!?

Alright, enough with the bad news, let’s have some good stuff now! To fix all of the above things, we only need one tool, but we have two. Yes, two! The first, and most important is SWIS Performance, which is included in all of our paid plans. But what does it do?

When you enable the Optimize Google Fonts feature, you need to visit your home page (or any page on your site). SWIS then searches through all your CSS looking for references to Google Fonts. Specifically, it’s looking for that @font-face code we mentioned earlier. Once it has that, it will inline the font CSS in your page, which eliminates our dastardly middleman: fonts.googleapis.com. This saves a minimum of 100-200ms, on a fast desktop connection.

Additionally, it makes sure font-display: swap is set on all your fonts, whether you added them ten years ago, or yesterday. It also makes sure you have the preconnect directive for fonts.gstatic.com at the top of your page HTML, so the fonts will load as quickly as possible.

Hosting Fonts

You can also use SWIS to self-host fonts, which is great for privacy. This is also where our other tool comes in. If you use our Easy IO CDN, also included in our paid plans, you don’t have to worry about whether your web server is delivering fonts as quickly as Google’s CDN–which honestly isn’t very quick. Instead, Easy IO transparently routes requests for Google Fonts through Easy IO, and masks your user’s information to prevent any privacy leaks. And it does all of this via the fastest CDN on the planet.

cdnperf ranks bunny.net #1

Preloading Fonts

Just when you thought we were done, there’s one more thing we can do to speed up fonts. Yup, we can read people’s minds and load the fonts before they even need them! Okay, okay, not really… However, you can now use the Preload Assets feature in SWIS Performance to load your fonts before anything else is loaded on the page. This way, by the time the browser has parsed all your CSS, the fonts will be ready to load. Or at the very least, they’ll be ready very quickly, so that any layout shifting caused by the change from a system font to your desired web font will be as tiny as possible.

Now, if you are using Google Fonts, there will likely be a dozen or more font files listed, so you only want to preload the ones actually used on your site. Also, you probably shouldn’t be preloading icon fonts like Font Awesome. Everything you preload means something else has to take a back seat, and it is highly unlikely that you’re using enough icons to make it worthwhile. If you want to preload your fonts, head over to our docs article which will walk you through the process. It won’t hurt, I promise!

And if you have any other questions about speeding up fonts, let us know!