Optimize Fonts to Speed Up Your Website
Tags: wordpress, font, speed, webdev
Published: 2022-03-04 09:25:09

> One of the main keys of optimizing or speeding up website performance is reducing the total requests and file size in a page. That will include Fonts. – [ThinkWeb](https://thinkweb.dev/)

Fonts are crucial to our page design. Using different font types can change the whole design character of our web page. Choosing the right font is as important as choosing the right design.

Unfortunately, fonts can make our site slow. Web designers often use multiple fonts just to support the character of their designs. Using multiple fonts means multiple file requests. This can hurt our website performance.

So, to ensure that we'll pass the [Core Web Vitals](https://thinkweb.dev/how-to/optimize-core-web-vitals/) score, fonts are also important to optimize.

## Optimizing Google Fonts

The most common method that people often use is by embedding fonts from the Google Fonts library. Yes, this is the easiest way for using fonts on our website. But it also has its drawbacks.

Serving fonts from google can actually reduce the speed performance of our website if we're not using it carefully and handling it properly.

Why?

1. There are so many unused bytes in their default CSS (Google Fonts CSS)
2. The amount of time to make the connections and fetch files from 2 different DNS resources can often make a huge render blocking time, especially if we have a large page size and uses so many assets.

Both may cost us warnings on our Core Web Vitals scores.

So, how can we optimize them?

**1. Self Host the Google Fonts CSS**

The default method to embeds font(s) from the Google Fonts library is by using link tag like this one:

```
<link href="https://fonts.googleapis.com/css2?family=Roboto:ital,wght@0,400;0,700;1,400;1,700&display=swap" rel="stylesheet">
```

If we open that url, we will find so many fonts css for multiple language. While all we need usually is just the Latin text only. By self-hosting the fonts css and select the latin fonts only, we can reduce the CSS size significantly.

**2. Inline the Google Fonts CSS**

As fonts are a part of the critical assets, it is best to inline the CSS in the `<head>` section to eliminate the need to fetch the style from the CSS file.

Here's an example for Roboto:

```
<style>
@font-face {
   font-family: 'Roboto';
   font-style: normal;
   font-weight: 400;
   font-display: swap;
   src: url(https://fonts.gstatic.com/s/roboto/v20/KFOmCnqEu92Fr1Mu4mxKKTU1Kg.woff2) format('woff2');
   unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
 }
</style>
```

**3. Limit the Font Families**

The font's file size isn't small, even if we use the woff2 extension. These are the woff2 file size of the 3 most frequently used Google Fonts.

![Fonts file size comparison](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/e8kg4gv8flhp50vpygw8.jpg)

So, even if we 'only' use 2 font combinations, the browser must download additional files of at least 20KB (gzipped) with an additional 4 font requests. And it will be more if we use more fonts.
Remember, all file requests are render-blocking. So we really should try to minimize the number of requests as much as possible.
Best Practice: Don't use more than 2 fonts.

**4. Limit the Font Variations**

In most cases, actually we don't need to embed the font files for bold and italic style, especially if we use the Sans-Serif Fonts families. The browser will still tilt and adjust the thickness if there's a `<strong>` and `<em>` tag as well as the font-weight: 700, font-weight: bold, and font-style, in the text CSS.
The results are often quite the same. Or at least, can be tolerated.

![Roboto font comparison](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/kb1yll6gttm0qcyce6sd.jpg)

**5. Filter the Characters**

![Roboto font characters](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/2aw4l1aq3sux2ya85q40.jpg)

The image above shows the types of characters in a regular Roboto font file. We don't actually need all of them, right?
If we only need the latin characters, we can filter the characters that we need from Google Fonts with something like this:

```
https://fonts.googleapis.com/css2?family=Roboto:wght@400;700&text=1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz@!-_+/\|/?%20&subset=latin&display=swap
```

*change the font name and the weight to everything that you need.

**6. Self Host the Font Files**

Self hosting our font files will always be faster than using the files served by Google Fonts CDN in terms of performance.
Here's the easiest way to do it:

- First, download the font file(s) directly using the font source url in the Google Fonts CSS, or use the [Google-WebFonts-Helper](https://google-webfonts-helper.herokuapp.com/fonts) created by Mario Rantfl.
- Then upload the file to our host using FTP or cPanel's File Manager.
- Finally, call the file via CSS.

```
@font-face {
   font-family: 'Roboto';
   font-style: normal;
   font-weight: 400;
   font-display: swap;
   src: url(/font-url-path/font-file-name.woff2) format('woff2');
}
```

**7. Preload the Critical Font Files**

Preload is useful for asking the browser to fetch the font file(s) right after the browser finish rendering the HTML, before fetching anything else.
We just need to put this in our `<head>` section.

```
/* Roboto Regular 400 */
<link rel="preload" href="https://fonts.gstatic.com/s/roboto/v20/KFOmCnqEu92Fr1Mu4mxKKTU1Kg.woff2" as="font" crossorigin>

/* Roboto Bold 700 */
<link rel="preload" href="https://fonts.gstatic.com/s/roboto/v20/KFOlCnqEu92Fr1MmWUlfBBc4AMP6lQ.woff2" as="font" crossorigin>
```
It should helps us avoid FOIT (Flash of Invisible Text), FOUT (Flash of Unstyled Text), and additional CLS (Cumulative Layout Shift).

**BONUS: Convert the Font File to Base64**

We can eliminate the need to fetch the font files by converting them into Base64 encoded string.
Just upload the files to Base64 online converters like [Gift Of Speed](https://www.giftofspeed.com/base64-encoder/), then copy and paste the base64 encoded string as the font's url source. The CSS code should be like this:

```
@font-face {
   font-family: 'Roboto';
   font-style: normal;
   font-weight: 400;
   font-display: swap;
   src: url(data:font/woff2;base64,OUR-FONT-BASE64-CODES;
 }
```
*_Important: A base64 encoded font string size are larger than the font file size itself. So it will be best to have it filtered first._

Hope this helps. You can read the original article [here](https://thinkweb.dev/how-to/optimize-fonts/).