Google Fonts is always a bottleneck for website performance. The Google Fonts' CSS is a render-blocking resource, which means that the browser won't render any processed content until the CSS is loaded. It also causes a blank space when the font is being loaded.
In the previous post of this series, I have shown you a way to get rid of these problems using a script from PerfPerfPerf. Since then, Google Fonts has some updates and the PerfPerfPerf's becomes outdated. And we need a better way to load Google Fonts now!
Google Fonts loading problems
Before going into the solution, let's summarize 2 issues above, as they are the most important problems with Google Fonts. And these are the problems we're going to resolve in this article.
Render-blocking CSS
When Google Fonts is being loaded, no further content (text, images, CSS, JavaScript, etc.) is loaded. That means your whole page is blocked until Google Fonts is finished loading.
This problem is critical because it freezes your website when loading and increases the loading time of the page. And because loading time is an SEO factor, your site might get a lower ranking.
Blank space while loading Google Fonts
Another problem with Google Fonts is that when it's being loaded, the text is completely vanished before your eyes. Only until it's finished loading, you can see the text.
That causes a really bad experience for your users. And if the loading time is huge, your users might think your website is broken (because they see nothing!).
How to fix Google Fonts problems
Load Google Fonts asynchronously
To solve the 1st problem of render-blocking, we need to load Google Fonts asynchronously. That means we'll load the Google Fonts' CSS without blocking loading or rendering other resources.
There are 2 solutions:
Preloading CSS with rel="preload"
preload
is a mechanism to load resources without any effect on loading the other ones. It also puts a higher priority on the resources that are preloaded. That means these resources will be load before other resources. You can read more about this on MDN.
Let's assume you want to load Roboto font. Google gives you the HTML like this:
<link href="https://fonts.googleapis.com/css?family=Roboto" rel="stylesheet">
To make the CSS preloaded, you need to change it to:
<link href="https://fonts.googleapis.com/css?family=Roboto" rel="preload" as="style" onload="this.rel='stylesheet'">
The CSS is now preloaded. And when it finishes loading, it'll be applied.
Unfortunately, preload is not supported on Firefox and IE. IE can be ignored, but Firefox is the 2nd popular browser in the world. To fix this problem, you can use a JavaScript polyfill (which I don't like because you have to load another resource to the web page) or use the 2nd solution below.
Using media type
Another solution is using media type, which is supported by all browsers. This technique is created by Filament Group. The HTML markup is simple as follows:
<link href="https://fonts.googleapis.com/css?family=Roboto" rel="stylesheet" media="print" onload="this.media='all'">
What it does is loads the CSS for the print-based media. In other words, the CSS is applied only when the users try to print the page. The loading process is now asynchronous (since we're on browsers). And when it's done, the CSS is applied for all media (which includes browsers).
I've been testing this technique for a while and see a good improvement in font loading. You can test on MetaBox.io and docs.metabox.io websites to see how it works.
Using font-display: swap
To solve the 2nd problem with a blank is when loading fonts, we need to use font-display: swap
. Basically, it allows us to display the text first with a fallback font family (usually serif
or sans-serif
). And when the font is loaded, it swaps the text into the wanted font.
The good news is Google Fonts now supports font-display: swap
by default. You can see it in the font URL like this:
<link href="https://fonts.googleapis.com/css?family=Roboto&display=swap" rel="stylesheet">
Notice the display=swap
in the URL. The CSS loaded for the font will have font-display: swap
.
This technique works in all browsers except IE and Edge. On these browsers, the font will still load normally. So, I think it's safe to apply it to our websites.
Just a note that the solution in the 1st part of this series, which uses PerfPerfPerf script, tries to add font-display: swap
to the Google Fonts' CSS. It's not needed anymore.
Apply Google Fonts loading techniques in WordPress
The best way to apply the techniques above is adding the code into your theme's header.php
file. Or you can create a child theme and modify the header.php
file. So your header.php
file will look like this:
<!doctype html> <html <?php language_attributes(); ?>> <head> <meta charset="<?php bloginfo( 'charset' ); ?>"> <meta name="viewport" content="width=device-width, initial-scale=1"> <link href="https://fonts.googleapis.com/css?family=Roboto&display=swap" rel="stylesheet" media="print" onload="this.media='all'"> <?php wp_head(); ?> </head> // Other code
I find it's harder to do this if you use page builders. You need to disable default Google Fonts and apply the code above. The only plugin I found that disables the Google Fonts is Autoptimize. Unfortunately, it removes our manual link
tag, too.
The best solution for page builders is using Autoptimize to preload the Google Fonts. You can turn it on the settings page:

You can see it in action on GretaThemes website.
Conclusion
After applying the new techniques to our websites, I'm quite happy with the result. The loading speed is increased and the FOUT effect is minimal. Users probably don't notice the font change (swapping). And of course, the Google PageSpeed Insights score is higher than before (in my test for MetaBox.io's homepage, it has 100 scores for desktops).
I think optimizing the loading speed for Google Fonts is very important for both users and search engines. And you should do it now. Feel free to discuss this with us on the Facebook group, or leave a comment below.
- The Fastest Way To Load Google Fonts In WordPress!
- The Fastest Way To Load Google Fonts In WordPress (Part 2)
Previously I was facing a very bad issue with google fonts. But I fixed it.
Thanks for the detailed tutorial.
Best Regards
Katia Cooper
Hi, great article. Lots of good info. I've been plagued with this problem for a while and even with Autoptimize set correctly (as per your suggestion) I still get preload messages from page insights. It's driving me crazy because this particular problem is causing Google's Search Console to label the site non-mobile friendly because of a high Last Content paintful score. The following is what I see from the preload message. Any ideas?
Consider using `` to prioritize fetching resources that are currently requested later in page load. Learn more.
URL
Potential Savings
…thrvicomoon/icomoon.ttf?jtzdu4(www.storey-lines.com)
12,360 ms
…fonts/rise-icomoon.woff?6xplcw(www.storey-lines.com)
12,210 ms
…font/Roboto.ttf(www.storey-lines.com)
7,410 ms
Hi Aaron, hope you found a fix ! if you found one let's share ^^
I am currently exactly in the same situation with Rise theme also.
What seems to be working for me is that kind of declaration in the HEADER :
BUT it's still not working with that strange "?6xplcw" at the end...
Any ideas welcome
Absolutely great work putting this together thank you. We've used it on our new WordPress site and saved 0.1 on load time which is brill!
I ran into a bit of a WordPress code maintenance problem is that I have three 'header.php' style files that have the standard header, then a variation for landing pages, and one for super simple pages. So on consideration, I didn't want to put the code directly into the tag as that would mean maintaining it in three files & with a number of contributors to the project it's not always easy to communicate that all our enquires are in our functions file apart from the fonts.
So taking inspiration from this post: https://wordpress.stackexchange.com/questions/34754/add-title-attribute-to-stylesheets-with-wp-enqueue-style I created the following flow so it can still be added using the standard WordPress actions:
Step one: Include register the google font's style sheet as usual in our enquiries function
wp_register_style('hrm-google-fonts', '//fonts.googleapis.com/css2?family=Montserrat:ital,wght@0,400;0,500;0,600;0,700;0,800;1,400;1,500;1,600;1,700;1,800&display=swap', false, null);
wp_enqueue_style('hrm-google-fonts');
Then after the enquire function with all the scripts and stylesheets i've added the following functions:
// Edit google fonts to add onload
function add_google_font_stylesheet_attributes( $html, $handle ) {
if ( 'hrm-google-fonts' === $handle ) {
return str_replace( "rel='stylesheet'", "rel='stylesheet' media='print' onload=\"this.media='all'\"", $html );
}
return $html;
}
add_filter( 'style_loader_tag', 'add_google_font_stylesheet_attributes', 10, 2 );
// Add No Script Google Font to Header
function add_google_font_noscript(){ ?>
<?php }
add_action('wp_head', 'add_google_font_noscript',11);