How to Optimize Google Font Loading to Fix Render Blocking Resources Page Speed Issue

Google Fonts have been around for many years. Adding custom web fonts to your site is a simple way to spice up the way it looks and enhance branding with stylish headings and text. Out of the box, using custom Google fonts on your website is as easy as adding a single line of HTML code to your page's <head></head> code-block. 

For example, here's the standard way to add the font Lato to your website:

<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Lato&display=swap">

Easy, right? Just like it's supposed to be.

However, if you're using more than two or three fonts then having a render-blocking <link> element can slow down page speed by increasing the loading time.

In order to avoid Google Fonts slowing down your website there are a few measures you can take to optimize how they're included on the page. Fortunately, the actual font files (WOFF2, WOFF, etc) aren't render-blocking – they will load in the background and be applied to the page, as specified by the CSS – so, that means optimization comes from eliminating the render-blocking effect.

Loading font CSS asynchronously allows you to achieve the goal. Cool, right?

Let's take a look at how to systematically optimize loading Google Fonts to your website.

Asynchronous Font Loading

First, to implement asynchronous loading you can use a combination of a mismatched media attribute and a simple inline JavaScript trick that updates the media attribute's value once the file is loaded.

<link media="print" onload="this.onload=null;this.removeAttribute('media');" href="https://fonts.googleapis.com/css2?family=Lato&display=swap" rel="stylesheet">

You see, once the file loads the JavaScript onload snippet removes the mismatched media attribute and let's the CSS and fonts do their thing like normal.

That alone is super duper cool, but you can do more too.

JavaScript Disabled Font Loading

Taking font optimization a step further, you can add a no-JavaScript fallback for people browsing with JavaScript disabled like so:

<noscript>
    <link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Lato&display=swap">
</noscript>

This way, you can still load custom Google Fonts when the onload code doesn't fire.

It's also a convenient way to fine tune the levels of font-loading customization. Since you know this method of font loading is more sluggish, you have an opportunity to serve up less fonts (if you want to) and save some page weight.

HTML Resource Hinting

In addition to asynchronous loading fonts, you can also use HTML resource hints. Resource hints can increase the loading priority in the browser and help people get a head start on loading the fonts you're trying to use.

There are two HTML resource hints that are useful to us in this scenario. First, preload. Second, preconnect.

Preload Resource Hint

The asynchronous loading method we're already using tells the browser to start loading the font CSS files straight away, but alone it's doing it with a low-priority. We want to increase the priority in an effort to better optimize loading and minimize layout-shifts, so we're going to add another <link> element, like so:

<link rel="preload" as="style" href="https://fonts.googleapis.com/css2?family=Lato&display=swap">

Preload is relatively straight forward. 

Preconnect Resource Hint

preconnect, is a little more fancy. Essentially, Google Fonts load the CSS file from one location (fonts.googleapis.com) and the actual font files from another (fonts.gstatic.com). The CSS domain is visible in the standard font <link>, but the font file's domain is not, so that's where preconnect comes in to hint to the browser to get a jump on that connection, too.

<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>

Supporting Older Browsers

One caveat is older browser's kind of suck. Not all of them play nice with preconnect, but you can achieve a similar effect and increase browser-support by adding yet another <link> element with a rel="dns-prefetch" property to accommodate if needed.

Full Results

Let's take a look at how it goes when you put everything together:

<head>
<!-- other head code -->

<!-- preconnect to the font file's domain -->
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>

<!-- (optional) increase loading priority of your fonts with preload -->
<link rel="preload" as="style" href="https://fonts.googleapis.com/css2?family=Lato&display=swap">

<!-- the awesome asynchronous JavaScript enabled font loading method -->
<link media="print" onload="this.onload=null;this.removeAttribute('media');" href="https://fonts.googleapis.com/css2?family=Lato&display=swap" rel="stylesheet">

<!-- the No-JavaScript fallback font loading method -->
<noscript>
    <link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Lato&display=swap">
</noscript>

</head>

And, that's how it's done. Streamline Google Font loading and fix the issues of render-blocking resources. You can check it's working by testing your website before and after adding the code using Google's PageSpeed Insights tool.