Google Fonts is a quite reliable service, and it can be said that its network performance is very good – it relies, of course, on Google’s global CDN.
However, the simple action of initiating an HTTP request for those fonts can lead to unnecessary Round Trip Times (RTT) before the request is actually routed to the server.
This is because the browser performs several actions before the request reaches the server:
- Resolving DNS
- Performing TCP handshake
- Negotiating TLS Tunnel – if talking about HTTPS request
We won’t elaborate on these actions in this article, but these actions (referred to as DNS, TCP, TLS) account for one to three RTT delays, causing latency before the actual request is routed to the server.
Modern browsers attempt to predict which connections are needed before the request to the server is actually made.
The browser tries to open the required connections before the server request is initiated by initiating preconnect
to specific domains, thus eliminating costly RTTs for those requests in the critical upper part of the page (Critical Path).
However, as sophisticated as modern browsers are, they cannot accurately predict all domains for which preconnect
will help on every site.
The good news is that we can assist the browser in such cases and essentially tell it which domains (or more accurately, which sockets
) we want to open before the requests themselves using the preconnect hint
, which is rel="preconnect"
.
Consider a daily situation in which we want to use preconnect
, such as loading Google Fonts to improve the loading time of your WordPress site.
Prior to continuing, it’s worth mentioning that a more “aggressive” action than preconnect, called preload, might be preferable for fonts. Use preload together with a proper setting of font-display, and you’re all set in this aspect.
Notice that it is recommended to use preload instead of preconnect if you host your google fonts locally.
What’s the issue with standard Google Fonts loading?
There’s one performance issue with font loading, and that’s the fonts starting to load later in the process. The following graph illustrates this problem clearly:
Note that in this graph, the browser fetches the html
and discovers that it needs some css
asset located on the fonts.gogleapis.com
domain.
Once it finishes downloading this css, it constructs the CSSOM and realizes that this page requires several fonts. Therefore, it initiates requests to each of them from the fonts.gstatic.com
domain.
Before that, as previously shown, it must perform the DNS, TCP, & TLS process, so only after these requests are completed, HTTP/2 multiplexing takes place.
<link href='https://fonts.gstatic.com' rel='preconnect' crossorigin>
<link href="https://fonts.googleapis.com/css?family=Assistant:300,400,700,800" rel="stylesheet">
Adding the above code to this blog results in the following:
In this graph, however, we add a preconnect hint
to the stylesheet that informs the browser of this site’s intention to fetch assets from the fonts.static.com
domain.
As a result, the browser initiates the connection in parallel with the css fetch and finishes it earlier. When it comes to requesting the fonts, there are no delays, and it loads the fonts immediately!
In this case, unnecessary upper part RTTs are saved, and a few milliseconds are gained. Notice that the browser also initiates the request earlier compared to the first scenario.
Since we all love WordPress, here’s how to add preconnect
when loading Google Fonts in WordPress. Pay attention to line 7 where we specify that the priority for the hook should be the highest by adding the number 0 to add_action
.
<?php
// BEGIN HERE //
function savvy_preconnect() { ?>
<link rel="preconnect" href="https://fonts.gstatic.com/" crossorigin>
<?php
}
add_action('wp_head', 'savvy_preconnect', 0);
Google Fonts use @font-face rules, and since the specifications require that the requests be made “anonymously,” the crossorigin attribute must be added to the preconnect hint we created.
What about browser support?
preconnect
has been supported in Chrome and Firefox for a long time, yet I don’t see widespread use of this option, especially on Israeli sites. It’s worth noting that browsers have the ability to decide how to treat this action (thus the term preconnect hint).
The browser can choose to perform only part of the DNS, TCP, TLS actions as it sees fit, and this is also the fallback for browsers that don’t support this option.
Regarding browser support, these are the versions of the supported browsers:
As usual, Microsoft is lagging behind in all matters related to these topics, but that’s not surprising…
Use preconnect Wisely
The preconnect
option is an important tool in your toolbox, not only for loading Google Fonts. As shown in the example above, using preconnect
saves roundtrip time, especially in the critical upper part of your site or application. In certain cases, it can save almost a second.
Despite this, use preconnect
wisely and ensure you’re not opening a connection that serves no purpose. As is customary in these optimization attempts, it’s advisable to check the impact of these actions using the right testing and optimization tools.
Beyond that, I assume you realize that you can use preconnect not only for fonts but also for any asset you wish to fetch to prevent unnecessary delays in the request.
By the way, if you’re interested in skipping the entire process in this post, you can load Google Fonts locally from your server (or CDN). Check out the article on locally loading fonts from Google.
Since I’m diving into this world recently, prepare for upcoming articles on topics like dns-prefetch, preload, and prerender 🙂 Feel free to share thoughts (and share the article!) along the way…