Optimize Google Fonts

📅 February 18th, 2020 6 min read

To make a website look beautiful, typography is a super important criteria to consider. A single element of design that can change the look of a site drastically. The first thing that comes to mind while thinking about this is probably the font-family that's gonna be used. And what better resource is out there than Google Fonts? When we use multiple fonts, it can take times to load. I'll try to share some tips that can improve the loading time of google fonts quite significantly. Let's get started.

I divided the story into 2 sections. The first one will be about the basic best practices. The later one will be about further scope of optimizations.


Best practices

⋅ Multiple fonts in a single request:

Often we use different fonts for different texts (heading/paragraph). Adding multiple line of requests separately for corresponding fonts can certainly improve the readability but multiple line of requests means asking for assets multiple times. So, requesting for multiple small assets separately is significantly slower than asking for a larger file once. That's why it's best to combine multiple fonts in a single request.

For an example, I used 'Great Vibes' for the logo, 'Ubuntu' for the titles and headings and 'Barlow' (Currently using 'Open Sans') for the contents and paragraphs. List of separate requests would look like:

<link
  href="https://fonts.googleapis.com/css?family=Great+Vibes"
  rel="stylesheet"
/>
<link href="https://fonts.googleapis.com/css?family=Ubuntu" rel="stylesheet" />
<link href="https://fonts.googleapis.com/css?family=Barlow" rel="stylesheet" />

But asking for all three of them in a single request is faster.

<link
  href="https://fonts.googleapis.com/css?family=Barlow|Great+Vibes|Ubuntu"
  rel="stylesheet"
/>

⋅ Specifying Styles:

This is not actually a way of optimizing, in fact it increases the loading time. But it's an option to get the best out of google fonts. So, use this only when you need to.

We use font styles like bold and italic often. You can specify that for better result while asking for the font. We can use bold or b for bold font-style and italic or i for italic style.

<link
  href="https://fonts.googleapis.com/css?family=Barlow|Great+Vibes:i|Ubuntu:b"
  rel="stylesheet"
/>

Here we're requesting for Great Vibes with italic and Ubuntu with bold style in addition.

if both bold and italic are required that can be mentioned as well.

<link
  href="https://fonts.googleapis.com/css?family=Barlow|Great+Vibes:i|Ubuntu:bi"
  rel="stylesheet"
/>

Mostly we use font-weights for controlling the thickness of the text font. That can also be mentioned instead of b or i in the link request. Then the stylesheet would look like:

<link
  href="https://fonts.googleapis.com/css?family=Barlow:300|Great+Vibes|Ubuntu:900"
  rel="stylesheet"
/>

All of these styles will only work if the styles are available for that font at the first place obviously. For example, Great Vibes font only has one font-weight of 400. So, if we ask for Great+Vibes:700, that won't be valid.

⋅ Only ask for the characters that're needed:

For the logo of my site I only need the characters S,W,a,e,i,m,r,s,t. In that case I can specify that using &text.

<link
  href="https://fonts.googleapis.com/css?family=Great+Vibes&text=SiamWrtes"
  rel="stylesheet"
/>

As a result, the characters that will be loaded are only the ones asked for. This can shave upto 90% off the size of request.

But be cautious:

If you specify &text for just a particular font, you have to ask for that font separately. Otherwise all the fonts will get only the specified characters.

<link
  href="https://fonts.googleapis.com/css?family=Great+Vibes&text=SiamWrites"
  rel="stylesheet"
/>
//Otherwise Barlow and Ubuntu will also request for only S,i,a,m,W,r,t,e,s
<link
  href="https://fonts.googleapis.com/css?family=Barlow:300|Ubuntu:900"
  rel="stylesheet"
/>

Optimize

You might've noticed the requests are not for any font files rather for stylesheets. The stylesheets are of various @font-face declarations. So, we have a minimum of 2 separate requests to different hosts — first for the stylesheet at fonts.googleapis.com, and then to a unique URL for each font hosted at fonts.gstatic.com.

So, it's better to self-host the fonts.

If you find the steps overwhelming, the least you should do is to preconnect..

<link rel="preconnect" href="https://fonts.gstatic.com/" crossorigin />
<link
  href="https://fonts.googleapis.com/css?family=Barlow:300|Ubuntu:900"
  rel="stylesheet"
/>

To make self-hosting hassle free, there's a wonderful tool created by Mario Ranftl. This provide full control over our font files, loading, and CSS properties. We can use it to download our fonts and provide basic CSS font-face declarations.

Modern Browsers provide WOFF and WOFF2 formats while best support will also give you TTF, EOT, and SVG. We will consider WOFF and WOFF2. Copy the provided CSS into your stylesheet at the beginning before you call any of the font families.

⋅ Preloading:

So far, we have only moved where we are hosting files from Google’s servers to ours. This is good but we can do better. We want our font files to be ready right away, not after the CSS is parsed and the CSSOM is created.

We can do this by preloading the assets.

Now the question comes what to preload? To answer that, all the browsers that support preload also support WOFF2 so we can safely choose only WOFF2.

<link
  rel="preload"
  as="font"
  type="font/woff2"
  href="./fonts/muli-v12-latin-regular.woff2"
  crossorigin
/>

<link
  rel="preload"
  as="font"
  type="font/woff2"
  href="./fonts/muli-v12-latin-700.woff2"
  crossorigin
/>

rel="preload" tells the browser to declaratively fetch the resource as="font" tells the browser what it will be downloading so that it can set an appropriate priority. type="font/woff2 tells the browser the file type so that it only downloads the resource if it supports that file type.

Not done yet

It's always recommended to use &display in the requested link

<link
  href="https://fonts.googleapis.com/css?family=Barlow:300|Ubuntu:900&display=swap"
  rel="stylesheet"
/>

While using the fonts in css we use theme like:

font-family: "Barlow", Segoe UI, sans-serif;

For &display=swap: The browser will initially show a fallback font, then once the Google Font has downloaded it will swap the fonts.

using display=swap force CSS to use Segoe UI or sans-serif (based on their availability) until Barlow is loaded and ready to be used, so that blank content is not displayed.

or &display=fallback: The browser will initially show a fallback font, if the Google Font is downloaded within 3 seconds it will swap the fonts. If the Google Font can’t download in 3 seconds or less it will continue using the fallback.

We can specify this in the CSS @font-face also

font-display: swap;
//or
font-display: fallback;

For further reading

- Making Google Fonts Faster⚡

- 4 Expert Tips for Getting the Most Out of Google Fonts - SitePoint

- Web Font Optimization | Web Fundamentals | Google Developers

- Font-display Playground