I’ve always been obsessed with making websites performant. Many sites that I build use Google Fonts, which are already kind of fast and with the introduction of font-display: swap
it’s become asynchronous in nature.
It’s like telling the browser that we are OK with the fact that the font loads right away which is unstyled. It’s what we call FOUT which means “Flash of Unstyled Text”. Now that when you load a website with Google fonts:
- It loads the text right away, unstyled that is
- Then when Google fonts are done downloading
- The text styles are replaced with the Google font
But if you follow Harry Roberts who’s a literal CSS Wizard, his experiments and research led to making Google Fonts even faster by ~20% to ~30%. Let me quote him:
If youβre going to use font-display
for your Google Fonts then it makes sense to asynchronously load the whole request chain.
Let’s make Google fonts load faster by following Harry’s findings.
Step #0: Selecting a Google Font#
Go to fonts.google.com
and select a font to be used by your site. Let’s say I selected the Montserrat font with 400 and 700 weight for both regular and italic font styles. Google suggests the following embed URL.
<link href="https://fonts.googleapis.com/css2?family=Montserrat:ital,wght@0,400;0,700;1,400;1,700&display=swap" rel="stylesheet">
Where the CSS URL looks like https://fonts.googleapis.com/css2?family=Montserrat:ital,wght@0,400;0,700;1,400;1,700&display=swap
β let’s call this URL $CSS
for the sake of simplicity in the following examples. Notice that the $CSS
URL includes &display=swap
at the end.
Step #1: Preconnect with fonts’ origin#
If you open the $CSS
URL above you’ll notice that the fonts are loaded from the origin that looks like https://fonts.gstatic.com
β we can preconnect
to this origin.
<!-- Preconnect to the fontsβ origin. -->
<link rel="preconnect"
href="https://fonts.gstatic.com"
crossorigin />
β
Preconnecting to the fonts’ origin is a good idea. It led up to 1200ms loading time saved on the first web page load.
Step #2: Async CSS Fetch#
You can use the Filament Groupβs simplest print media type trick.
<link rel="stylesheet"
href="$CSS&display=swap"
media="print" onload="this.media='all'" />
Here we ask the browser to load the CSS asynchronously with the print
context but as soon as the CSS file is loaded we apply it to the all
context.
As a result in Harry’s research, the site’s First Paint is up by 1.6s to 1.7s. However, the first web font however was loaded 500ms slower due to the low priority. Sadly, the print
stylesheets are loaded with super low priority.
β οΈ While asynchronous CSS is an overall good idea we need to make the CSS loading a high priority.
Step #3: High-priority async CSS Fetch#
In modern browsers, you can make the async CSS fetch high-priority by preloading
the $CSS
file.
<link rel="preload"
as="style"
href="$CSS" />
Preloading a Google font turns out to be a great idea, Harry found out that the first web font load was 600ms faster than usual. Which means we can use preloading in combination with the print media trick. I’ll recommend using preload
trick first and then as a fallback we use the print
media trick mentioned in step #2.
β
preload
a Google font is a great idea.
Step #4: Load CSS when JavaScript is disabled#
For instances where a user has intentionally disabled JavaScript in their browser, we can use the <noscript>
tag to load the original $CSS
as a fallback to everything.
<noscript>
<link rel="stylesheet" href="$CSS&display=swap" />
</noscript>
Final Snippet#
Finally we end up with the following snippet.
<!-- [STEP #1] -->
<link rel="preconnect"
href="https://fonts.gstatic.com"
crossorigin />
<!-- [STEP #3] -->
<link rel="preload"
as="style"
href="$CSS&display=swap" />
<!-- [STEP #2] -->
<link rel="stylesheet"
href="$CSS&display=swap"
media="print" onload="this.media='all'" />
<!-- [STEP #4] -->
<noscript>
<link rel="stylesheet"
href="$CSS&display=swap" />
</noscript>
I most definitely recommend checking out the author’s research and finding here to gain up to 20% load performance improvement for Google fonts.
Direct Link β
Hi there, I’m interested in testing this snippet. I can’t figure out how to use $css. Do you have a final script with that variable being used?
I can’t figure out the part with the $css variable. I don’t see this in the provided snippet. Also do I need to include “&display=swap” to it? In the link declaration I see this tag “$CSS&display=swap”. So I think not. But I’m not 100% sure on this. Could you help me? Thanks.
As written above, the entire link from Google is
$css
variable. That is$css
===https://fonts.googleapis.com/css2?family=Montserrat:ital,wght@0,400;0,700;1,400;1,700&display=swap
Very nice article, thank you for writing it.
How would this work with wp rocket installed on generatepress/oceanwp theme? I can write code but I’m not a developer. Thanks in advance!