DEV Community πŸ‘©β€πŸ’»πŸ‘¨β€πŸ’»

DEV Community πŸ‘©β€πŸ’»πŸ‘¨β€πŸ’» is a community of 964,423 amazing developers

We're a place where coders share, stay up-to-date and grow their careers.

Create account Log in
Cover image for Optimize Fonts to Speed Up Your Website
Arya Dhiratara
Arya Dhiratara

Posted on • Originally published at thinkweb.dev

Optimize Fonts to Speed Up Your Website

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

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 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">
Enter fullscreen mode Exit fullscreen mode

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>
Enter fullscreen mode Exit fullscreen mode

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

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

5. Filter the Characters

Roboto font characters

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
Enter fullscreen mode Exit fullscreen mode

*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 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');
}
Enter fullscreen mode Exit fullscreen mode

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>
Enter fullscreen mode Exit fullscreen mode

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, 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;
 }
Enter fullscreen mode Exit fullscreen mode

*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.

Oldest comments (1)

Collapse
 
digital_hub profile image
hub

good day dear Arya

many thank you so much for spending your time creating and posting this article.

i just found your article and i like it. The way you talk about Fonts and Wordpress-development.

Many thanks for the article it is just great!! It looks very promising and your thoughts regarding the usage of Fonts-Optimization for Wordpress
development are interesting. Many thanks for your inspiring ideas.

i am currently working on some issues - that have to do with the CSS and google fonts.

to begin with the beginning:i have found out that my wordpress-site fetches two google fonts:

one of them is montserrat

i decided to host them locally. so i have to

a. fetch the fonts
b. correct the css code

with the following tool i fetch them

google-webfonts-helper.herokuapp.c...

here i have the option to add the paths - to customize the path in the css-data

/* montserrat-regular - latin / u/font-face { font-family: 'Montserrat'; font-style: normal; font-weight: 400; src: url('../fonts/montserrat-v25-latin-regular.eot'); / IE9 Compat Modes / src: local(''), url('../fonts/montserrat-v25-latin-regular.eot?#iefix') format('embedded-opentype'), / IE6-IE8 / url('../fonts/montserrat-v25-latin-regular.woff2') format('woff2'), / Super Modern Browsers / url('../fonts/montserrat-v25-latin-regular.woff') format('woff'), / Modern Browsers / url('../fonts/montserrat-v25-latin-regular.ttf') format('truetype'), / Safari, Android, iOS / url('../fonts/montserrat-v25-latin-regular.svg#Montserrat') format('svg'); / Legacy iOS */ } Customize folder prefix (optional):

and now i have to add a path to set the correct path - (that means to customize the path )

../fonts/

some additional thought: what makes me wonder is the fact that some of the examples show full paths as reference - others dont:

see the following examples;

a. wp-ninjas.de/wordpress-google-font...

url("https://wp-ninias.de/fonts/muilti-latin-300.woff2") format (
url("https://wp-ninias.de/fonts/muilti-latin-300.woff") format (

b. pixelgrade.com/docs/advanced-custo...

Copy the URL Path field and paste it before each URL in the Embed Code field. The example code will look like this:

@font-face {
font-family: 'Name of the font';
src: url('http://yourwebsite.com/wp-content/uploads/fonts/11148/name-of-the-font-file.woff2') format('woff2'),
url('http://yourwebsite.com/wp-content/uploads/fonts/11148/name-of-the-font-file.woff') format('woff');
}

c. themeisle.com/blog/custom-fonts-wo...

Once the file is in place, open up your child theme’s stylesheet. Now you’ll need to call on that font so you can use it, via a snippet that should look like this:

`

@font-face {
font-family: New Font;
src: url(yourwebsite.com/wp-content/themes/...);
font-weight: normal;
}

`

and now compare it with the following example here:

  1. Copy CSS: (default is Best Support) Modern Browsers Choose Best Support if old browsers still need to be supported. Formats in this snippet: [eot,woff,woff2,ttf,svg]

Code:
/* montserrat-regular - latin */
@font-face {
font-family: 'Montserrat';
font-style: normal;
font-weight: 400;
src: url('../fonts/montserrat-v25-latin-regular.eot'); /* IE9 Compat Modes */
src: local(''),
url('../fonts/montserrat-v25-latin-regular.eot?#iefix') format('embedded-opentype'), /* IE6-IE8 */
url('../fonts/montserrat-v25-latin-regular.woff2') format('woff2'), /* Super Modern Browsers */
url('../fonts/montserrat-v25-latin-regular.woff') format('woff'), /* Modern Browsers */
url('../fonts/montserrat-v25-latin-regular.ttf') format('truetype'), /* Safari, Android, iOS */
url('../fonts/montserrat-v25-latin-regular.svg#Montserrat') format('svg'); /* Legacy iOS */

see the helper-tool google-webfonts-helper.herokuapp.c...

the question: so the question is: how to set the path correct for the CSS... which path should we use here!?

Dear Arya i look forward to hear from you

Take a look at this:

Settings

Go to your customization settings to nudge your home feed to show content more relevant to your developer experience level. πŸ›