DEV Community

Ben Halpern
Ben Halpern

Posted on

What's the most efficient way to load custom fonts on the web

DEV only uses system fonts to prioritize performance over other concerns... But I know there are new techniques and APIs for font loading consistently rolling out.

In 2020 and beyond, what's the outlook for font loading?

Top comments (20)

Collapse
 
mikaelgramont profile image
Mikael Gramont

I don't see any mention yet of Harry Roberts' excellent post on speeding up Google Fonts: csswizardry.com/2020/05/the-fastes...

This is the TLDR;

<!--
  - 1. Preemptively warm up the fonts’ origin.
  -
  - 2. Initiate a high-priority, asynchronous fetch for the CSS file. Works in
  -    most modern browsers.
  -
  - 3. Initiate a low-priority, asynchronous fetch that gets applied to the page
  -    only after it’s arrived. Works in all browsers with JavaScript enabled.
  -
  - 4. In the unlikely event that a visitor has intentionally disabled
  -    JavaScript, fall back to the original method. The good news is that,
  -    although this is a render-blocking request, it can still make use of the
  -    preconnect which makes it marginally faster than the default.
  -->

<!-- [1] -->
<link rel="preconnect"
      href="https://fonts.gstatic.com"
      crossorigin />

<!-- [2] -->
<link rel="preload"
      as="style"
      href="$CSS&display=swap" />

<!-- [3] -->
<link rel="stylesheet"
      href="$CSS&display=swap"
      media="print" onload="this.media='all'" />

<!-- [4] -->
<noscript>
  <link rel="stylesheet"
        href="$CSS&display=swap" />
</noscript>```



Half of this is applicable to self-hosted fonts, too.
Enter fullscreen mode Exit fullscreen mode
Collapse
 
louisefindlay23 profile image
Louise

It's a great article. I've been using this too.

Collapse
 
iamschulz profile image
Daniel Schulz

Self hosted fonts are the best way to go, but google fonts is still pretty fast. Be sure to keep your assets on a CDN.

Formats used to be a mess. Nowadays, I usually just keep it at woff and woff2. That covers all modern browsers and IE11. Everything else can safely fall back to a system font.

You can strip out characters you don't need. If you write exclusively in english, let go of all the pesky umlauts, northern ligatures and cyrillic character sets. That goes for iconfonts as well, strip out any icons you don't need.

Font display is a really nice tool to prevent font flashes (as in, your font didn't download yet). You can set a fallback font until the webfont is loaded, or just leave it at the fallback, if the webfont takes a long time to download. Chances are, the user has already begun reading at that point.

As with any asset, you can preload it with

<link rel="preload" href="/path/to/font.woff2" as="font" crossorigin>

. It moves the font further up the waterfall diagram and prioritizes it higher.

And last but not least, if you use lots of font styles of the same family, variable fonts are worth checking out. They let you use one (quite large) font file and style its properties (like thickness, slant, and custom ones) in css dynamically.

Collapse
 
sergix profile image
Peyton McGinnis

One of the most underrated tools for font loading is the unicode-range property for @font-face loading. It can really help decrease bundle sizes and loading times, especially when loading more than 2 fonts and the content is in one primary language.

Collapse
 
wuz profile image
Conlin Durbin • Edited

unicode-range and variable fonts are probably the fastest ways to do it!

I have this file on my personal site, which loads the Recursive font in two sections - the first is a tiny subset needed for English (the language I primarily write in). There is a great explanation of unicode-range here.

@font-face {
  font-family: 'Recursive';
  src: url('/fonts/recursive-0020_007F.woff2') format('woff2');
  unicode-range: U+0020-007F; /* The bare minimum for the English Language */
}

@font-face {
  font-family: 'Recursive';
  src: url('/fonts/recursive.woff2') format('woff2');
  unicode-range: U+00A0-00FF, U+0100-017F; /* additional glyphs */
}
Enter fullscreen mode Exit fullscreen mode

The other big win is using variable fonts - they limit the amount of code needed to deliver a wide range of fonts by encoding how the font changes at different widths, slants, and styles directly in the font file. Recursive is what I use, but there are a good number of other variable fonts out there!

recursive.design/
v-fonts.com/

Collapse
 
ben profile image
Ben Halpern

Thank you this is a really good reply! I did not know about unicode-range.

Collapse
 
wuz profile image
Conlin Durbin

Yeah, it's a great tool, but I don't see a ton of people working with it, but it's sooo good.

Collapse
 
jsn1nj4 profile image
Elliot Derhay • Edited

There are a lot of good responses here. I'm going to have to look into some of these.

Also, I agree that system fonts perform best. But when it comes to branding, I think it'll be hard to convince someone who wants the same fonts used everywhere to do something else for web, especially if it's someone who gets hung up on the look of something before even seeing the actual content.

Of course, that's not to say the performance argument shouldn't be made. Just wanted to throw this out there.

Collapse
 
khrome83 profile image
Zane Milakovic

Can’t believe no one mentioned subfont.

It creates a local copy for you if you host it on google. It rewrites the font tags. It uses a graph to see what you use and prunes the fonts for just the characters needed. And probably 20 more things I didn’t think of.

I run it against a static site after generating. Not sure how to work this into our workflows.

github.com/Munter/subfont

Collapse
 
0x11dfe profile image
Tesla

If you are using a common font such as Roboto, Open Sans your navigator might be storing the font locally itself so you could use local within src.

@font-face {
  font-family: 'Roboto';
  src: local('Roboto'), local('Roboto-Regular'),
  url('/resources/fonts/roboto/woff2/roboto-regular.woff2') format('woff2'),
  url('/resources/fonts/roboto/woff/roboto-regular.woff') format('woff'),
  url('/resources/fonts/roboto/truetype/roboto-regular.ttf') format('truetype');
  font-weight: 400;
  font-style: normal;
  font-stretch: normal;
  font-display: swap;
  unicode-range: U+000-5FF;
}
Collapse
 
jsn1nj4 profile image
Elliot Derhay

That's interesting. I bet we could test that out on a site my employer owns.

Collapse
 
helderberto profile image
Helder Burato Berto • Edited

Today I was reading Making Google Fonts Load ~20% Faster article about this subject.

Collapse
 
bernardbaker profile image
Bernard Baker

I tend to use Google Fonts. And stick to the system fonts. But hosting the fonts on the CDN as a very good idea. I completely forgot about link rel preload. I've created and used various font preloaders for various formats. Google fonts do the trick.

As for font flashing I used a trick many years ago which was to render the font off screen before hand. This discussion is enriching.

Collapse
 
patarapolw profile image
Pacharapol Withayasakpunt

Is it possible to stream fonts as opposed to load fonts? For example, HanaZono is around 20MB x2 files, and it covers most CJK characters, many of which are rare and you might not need.

Otherwise, split fonts on server-side?

Collapse
 
nickytonline profile image
Nick Taylor

I was using webfontloader in the previous version of my site.

GitHub logo typekit / webfontloader

Web Font Loader gives you added control when using linked fonts via @font-face.

Web Font Loader

Web Font Loader gives you added control when using linked fonts via @font-face. It provides a common interface to loading fonts regardless of the source, then adds a standard set of events you may use to control the loading experience. The Web Font Loader is able to load fonts from Google Fonts, Typekit, Fonts.com, and Fontdeck, as well as self-hosted web fonts. It is co-developed by Google and Typekit.

Build Status

Contents

Get Started

To use the Web Font Loader library, just include it in your page and tell it which fonts to load. For example, you could load fonts from Google Fonts using the Web Font Loader hosted on Google Hosted Libraries using the following code.

<script src="https://ajax.googleapis.com/ajax/libs/webfont/1.6.26/webfont.js">

I was using Gatsby under the hood, so webfontloader was wrapped in this Gatsby plugin, gatsby-plugin-web-font-loader.

Collapse
 
meatboy profile image
Meat Boy • Edited

Custom CDN and preloading with HTTP. I don't like Google fonts, not because they are slow but because loading fonts we share data with third party service (similar mechanism to fb pixel).

Collapse
 
thejsdev profile image
the JS DEV

Who knows

Collapse
 
andrewpillar profile image
Andrew Pillar

Pedantic answer, don't. I'd prefer to use the system fonts to try and make the website feel more native to the platform the user is on.

Collapse
 
fayaz profile image
Fayaz Ahmed

display swap is interesting, but even after implementing, lighthouse flags it.

Collapse
 
manishfoodtechs profile image
manish srivastava

There are different ways. But you want something blazing fast then here is a trick...

dev.to/manishfoodtechs/server-push...

110% faster next-time ...