Beginners Guide to Web Performance: Optimizing Google Fonts
Tags: webdev, webperf, frontend, fonts
Published: 2021-09-19 19:12:30

## How to Improve Web Performance by Optimizing Google Fonts

* [Use font-display: swap](#swap)
    - [Preconnect](#preconnect)
* [Serve Fonts Locally](#local)
    - [Use Google Webfonts Helper](#helper)
    - [Convert Google Fonts Manually](#manual)

### Introduction <a name="intro"></a>
This is a continuation of my Web Performance posts, with the [first focusing on images](https://dev.to/dianale_dev/beginners-guide-to-web-performance-optimizing-images-1fab). Today we will be optimizing fonts with a focus on Google Fonts. I was also planning to discuss FontAwesome, but that topic is long enough to warrant its own blog post later.

### Use font-display: swap <a name="swap"></a>
The first and easiest step to optimize fonts is to use `font-display: swap` on any fonts that need to be loaded - in combination with a web safe fallback font. This applies to all externally loaded fonts, not just Google Fonts. If you are embedding the link from the external site to your `<head>`, the font provider needs to have this feature. This was available on [Adobe Typekit](https://helpx.adobe.com/fonts/using/font-display-settings.html) finally as of September 2020.

>**Note: font-display: swap does not work with font icons!**

If you are copying the embed code from Google Fonts, they have conveniently added this for you (along with some other link tags with preconnect we'll discuss in a bit):
```html
<link href="https://fonts.googleapis.com/css2?family=Roboto&display=swap" rel="stylesheet"> 
```
So what does `font-display: swap` do? Because there will always be some delay in loading external fonts or from a font file, you don't want the user to see a blank screen until fonts are loaded. This will load the fallback font so users can read the site until your other fonts finish loading, and then they will _swap_ out and your fallback font will be replaced with the actual font. This of course means that you want to have a web safe fallback font:
```css
font-family: 'Roboto', sans-serif;
```
When the page loads, the browser fetches Roboto from Google Fonts and displays sans-serif for the user until Roboto finishes loading. This will lead to something known as **FOUT** or "flash of unstyled text", which is when the user can see the font family change as they view the page, which can be disruptive. There are other `font-display` values you can use depending on personal preference, but `swap` is the only one that doesn't block the text from showing up when the page loads. You can read about the other methods in detail [here](https://css-tricks.com/almanac/properties/f/font-display/).
#### Preconnect <a name="preconnect"></a>
You'll notice that Google Fonts also gives you some other link tags:
```html
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
```
The "preconnect" asks the browser to connect to another domain in advance before the browser discovers that domain on its own. Because text is so crucial to a web site, here Google is saying, "Hey browser, I'm going to need to load fonts from these external servers and you won't discover it until later, so I'm letting you know ahead of time to connect now."

>**Super Tip: Make sure that you are only calling the font weights and styles that will actually be used. I've seen many sites that call extra fonts that are never used in the CSS and this leads to unnecessary downloads.**

### Serve Fonts Locally <a name="local"></a>
Even with the updated performance code from Google Fonts and with using preconnect, the browser still has to make a connection to another server in order to download your fonts. The new strategy is to load fonts locally instead because you'll probably see better performance staying on the same server.

Years ago the advantage of linking to Google Fonts was that if other sites also used the same fonts as your site, you could take advantage of browser caching. If users visited another site using the same Google Fonts as yours, when they visited your site afterwards they wouldn't need to download the font files again. This benefit went away with [Chrome cache partitioning](https://developers.google.com/web/updates/2020/10/http-cache-partitioning).

The way fonts are called locally via CSS has always been a bit cumbersome to me. There was always the question of how many different font files you needed in order to maximize browser compatibility. When Internet Explorer had greater support, this could result in 500 kB of pure font files. Thankfully nowadays, you should be safe with supplying only woff and woff2. Unfortunately Google Fonts only provides you with ttf, so these need to be converted.

#### Use Google Webfonts Helper <a name="helper"></a>
The most convenient way to set up Google Fonts locally is using [Google Webfonts Helper](https://google-webfonts-helper.herokuapp.com/fonts) to generate the CSS for you, but don't forget to add `font-display: swap`. Also be sure to check your fonts are loading correctly; I had an issue with the "Inter" font that is a known issue in the [Github](https://github.com/majodev/google-webfonts-helper) repository. 

#### Convert Google Fonts Manually <a name="manual"></a>
You can download all the font files in a zip file directly from Google Fonts. But now you must convert the ttf files to both woff and woff2. There are many free online converters and [here's one](https://onlinefontconverter.com/) I tested to make sure it matched the Google Font.

Once you've downloaded the files, create a folder in your directory to store the woff/woff2 files, and then call them in your CSS like so (make sure the font styles, url and file names match your specific setup):
```css
@font-face {
   font-family: 'Roboto';
   font-style: normal;
   font-weight: 400;
   font-display: swap;
   src: local(''),
        url('../fonts/Roboto-Regular.woff2') format('woff2'), /* Chrome 26+, Opera 23+, Firefox 39+ */
        url('../fonts/Roboto-Regular.woff') format('woff'); /* Chrome 6+, Firefox 3.6+, IE 9+, Safari 5.1+ */
}

body {
   font-family: 'Roboto', sans-serif;
} 
```

### Conclusion
This will be a minor improvement to overall performance, but the changes are relatively simple compared to other web performance strategies. Since text content is so crucial I believe it's worthwhile to make these updates and I hope you are able to make improvements to your sites.