This article was originally posted in my personal blog.
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:
/* 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:
/* 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.
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?
/* 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.
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 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
<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 :)
Top comments (3)
Great tips on managing custom fonts! Efficient font loading can definitely boost performance and enhance user experience invisible text generator. Optimizing font delivery is key to keeping pages fast and smooth.
This is really useful & what most people should be doing. Good stuff. 👍
Do you know if there is a way to merge font files? I have three, but I only want one file.
Thanks! Glad that you learn some from my post :)
Do you mean you want to combine different typefaces (regular, italic, bold, etc.) to one font file? I think it is not possible to do so for web fonts. Maybe you can learn more from here.