How to load your custom fonts in a smart way
Tags: fonts, googlefonts, optimize, performance
Published: 2019-06-01 09:27:44

---
title: How to load your custom fonts in a smart way
published: true
description: Thanks to the improvement of bandwidth, it is fast to load everything even you have large images in the site. However, this may harm your user's surfing experience. One of the hurdles is your fancy fonts.
tags: fonts, google fonts, optimize, performance
cover_image: https://thepracticaldev.s3.amazonaws.com/i/nszasbyhyi68u75221d9.jpg
canonical_url: https://blog.atrera.com/css/performance/2019/06/01/how-to-optimize-your-fonts-in-website
---

_This article was originally posted in my [personal blog](https://blog.atrera.com/css/performance/2019/06/01/how-to-optimize-your-fonts-in-website)._

Nowadays, the size of the webpage is bigger than before. Thanks to the improvement of bandwidth, it is fast to load everything even you have large images in the site. 

However, this may harm your user's surfing experience. One of the hurdles is your fancy fonts.

## The Problem

For example, you have a multi-language website and each language has its own custom fonts, for example, English and Japanese. The user would need huge bandwidth to load your site. Moreover, they will see "flash of invisible text" or so-called FOIT.

How to solve this problem?

---

### 1. Use modern font type (woff and woff2)

First, review your css files which defined font-face. It should be something like this:

```css
/* roboto-regular - latin */
@font-face {
  font-family: 'Roboto';
  font-style: normal;
  font-weight: 400;
  src: url('../fonts/roboto-v19-latin-regular.eot?#iefix') format('embedded-opentype'), /* IE6-IE8 */
       url('../fonts/roboto-v19-latin-regular.woff') format('woff'), /* Modern Browsers */
       url('../fonts/roboto-v19-latin-regular.woff2') format('woff2'), /* Super Modern Browsers */
       url('../fonts/roboto-v19-latin-regular.ttf') format('truetype'), /* Safari, Android, iOS */
       url('../fonts/roboto-v19-latin-regular.svg#Roboto') format('svg'); /* Legacy iOS */
}

```

Now you can see, there are lots of font type in order to support different browsers. `woff` and `woff2` for modern browsers, `truetype` and `embedded-opentype` for legacy browsers etc. 

Actually, the loading order of font is based on the order in src. That means, if you want the browser to load `truetype` first, you can put it at the top. In this example, the browser will load `eot` first. 

Unfortunately, `eot` is not optimized like `woff` and `woff2`, i.e. not compressed. It is better to always load `woff` or `woff2`, both are supported by modern browsers and have built-in compression. With compression, their file size is relatively smaller than `eot` etc.

For this example, better to change to:

```css
/* roboto-regular - latin */
@font-face {
  font-family: 'Roboto';
  font-style: normal;
  font-weight: 400;
  src: url('../fonts/roboto-v19-latin-regular.woff2') format('woff2'), /* Super Modern Browsers */
       url('../fonts/roboto-v19-latin-regular.woff') format('woff'), /* Modern Browsers */
       url('../fonts/roboto-v19-latin-regular.eot?#iefix') format('embedded-opentype'), /* IE6-IE8 */
       url('../fonts/roboto-v19-latin-regular.ttf') format('truetype'), /* Safari, Android, iOS */
       url('../fonts/roboto-v19-latin-regular.svg#Roboto') format('svg'); /* Legacy iOS */
}

```

The browser will automatically fallback to next entry if it does not support `woff2`. 

### 2. Use font-display to load faster

To prevent "flash of invisible text", better to use `font-display` in your stylesheet.

```css
font-display: auto;
font-display: block;
font-display: swap;
font-display: fallback;
font-display: optional;
```

In default, the browser uses auto, and normally means `font-display: block`, this setting will block browser to load text before finished loading custom fonts. That is why the user will see a flash of unstyled text.

The other settings `swap`, `fallback` and `optional` have different block periods, so you can choose the one suits you. 

For example, you have a header using a custom font and you just want to show it in custom fonts, you can use `fallback`. The browser will hide the text for about 100ms and, if the font has not yet been downloaded, will use the fallback text.

Think carefully about what you need, then you should be able to discover the best option for your website.

> If you are using Google fonts, now you can set font-display by adding `&display=<your-display-type>` at the end of Google Fonts link. For example: https://fonts.googleapis.com/css?family=Noto+Sans+JP&display=block.

### 3. Unicode-range subsetting

For a website which has different languages, for example, a single page app (SPA) with Japanese and English version, normally both have different font-face. It is a waste if you open an English page but the browser also loads Japanese custom fonts, right? How can we solve this issue?

```css
/* Japanese fonts example */
@font-face {
  font-family: 'Noto Sans JP';
  font-style: normal;
  font-weight: 400;
  src: url('../fonts/noto-sans-jp-v23-latin-regular.woff2') format('woff2'), /* Super Modern Browsers */
       url('../fonts/noto-sans-jp-v23-latin-regular.woff') format('woff'), /* Modern Browsers */
       url('../fonts/noto-sans-jp-v23-latin-regular.eot?#iefix') format('embedded-opentype'), /* IE6-IE8 */
}

```

The solution: `unicode-range`. If you set the unicode range, the browser will load the most suitable fonts for each language. Normally, English should be `unicode-range: 0020—007F`. For more languages, you can check it in [unicode-table](https://unicode-table.com/en/).


### 4. Host your fonts locally or in CDN

One of the bottlenecks of loading fonts is speed. If you need to call your fonts from another server, like Google Fonts, the page may need more time to load. Use [Google Font Helper](https://google-webfonts-helper.herokuapp.com/fonts) to download all font files and host it your own.

When your fonts load faster, the chance of getting FOIT should be lesser.

### 5. Preload your fonts

A minor that most of the developers forget is the preload tag. To make your fonts load faster, you can add `preload` to your font files. Unfortunately, this trick is not available in all browsers, like Firefox, is still not available to use `preload`. For more details, view [caniuse.com](https://caniuse.com/#search=preload)

```html
<link rel="preload" href="fonts/cicle_fina-webfont.woff2" as="font" type="font/woff2" crossorigin>
```
---

## Final

Hope you enjoy this post! Welcome to share your thoughts or tricks on web performance :)

---

## Read More

1. [Web Font Optimization](https://developers.google.com/web/fundamentals/performance/optimizing-content-efficiency/webfont-optimization)
2. [font-display - MDN](https://developer.mozilla.org/en-US/docs/Web/CSS/@font-face/font-display)
3. [font-display - CSS-Tricks](https://css-tricks.com/almanac/properties/f/font-display/)