Performance

Web Fonts and Speed: Best Practices for Fast Typography

Custom fonts can delay text and shift layout. Learn font-display, WOFF2, subsetting, preloading and self-hosting to keep your typography fast and stable.

By Zebra Hosting Cloud

Custom fonts give a site personality, but they are files the browser must download before it can show text in the intended style. Badly handled, fonts cause invisible text, a flash of different type, or text that jumps when the real font arrives. Handled well, they cost a few kilobytes and go unnoticed.

What goes wrong with fonts

  • Flash of invisible text (FOIT): the browser hides text until the font loads, so visitors stare at a blank space. Browsers typically cap how long they wait, but the delay is real.
  • Flash of unstyled text (FOUT): the page shows a fallback font first and swaps when the custom font is ready. Better than blank, but it can shift the layout.
  • Heavy downloads: every weight and style is a separate file, so regular, italic, bold and bold italic quickly become four requests.
  • Late discovery: fonts referenced in a stylesheet are only found after that stylesheet downloads and the browser knows the text needs them.

Use WOFF2

WOFF2 is the modern web font format, with built-in compression that makes files considerably smaller than older TTF or WOFF files. Every current browser supports it, so you can usually offer WOFF2 alone and drop older formats.

Control the loading behaviour with font-display

The font-display descriptor in your @font-face rule tells the browser how to behave while the font loads.

ValueBehaviourGood for
swapShow fallback immediately, swap when readyBody text where readability comes first
fallbackVery short hidden period, short swap windowBalanced default
optionalUse the font only if it is available almost immediatelyAvoiding layout shift entirely
blockHide text for a periodIcon fonts where fallback is meaningless
@font-face {
  font-family: "Brand Sans";
  src: url("/fonts/brand-sans.woff2") format("woff2");
  font-weight: 400;
  font-display: swap;
}

Self-host your fonts

Loading fonts from a third-party service adds a DNS lookup and a connection to another domain, and in the past browsers could share cached copies across sites, but modern browsers separate caches by site, so that advantage is gone. Hosting the files on your own domain lets them travel over the connection (and SSL certificate) you already have, lets you set long cache lifetimes, and removes a dependency. It also avoids sending visitor requests to an outside service, which is worth considering for privacy compliance. Many font libraries let you download the files for self-hosting, subject to their licence.

Preload the important fonts

Telling the browser early about the one or two fonts used above the fold saves a round trip:

<link rel="preload" href="/fonts/brand-sans.woff2" as="font" type="font/woff2" crossorigin>

The crossorigin attribute is required for fonts even on the same domain. Preload only what you need immediately. Preloading everything competes with images and scripts and defeats the purpose.

Cut the number and size of files

  • Limit weights: two weights, such as regular and bold, are enough for most designs.
  • Skip italics unless you truly use them, or let the browser synthesise them for minor uses.
  • Subset the font to the character sets you need. A site in English and a few European languages does not need Cyrillic or Greek glyphs. The unicode-range descriptor lets browsers download only the subsets a page uses.
  • Consider variable fonts: one file covers a range of weights, which can be smaller than several static files when you need many weights.
  • Use system fonts for body text if brand rules allow it: they cost nothing to load.

Prevent layout shift when the font swaps

When fallback and custom fonts have different proportions, text reflows on swap. You can reduce that by picking a fallback with similar widths and using the CSS descriptors size-adjust, ascent-override and descent-override in a fallback @font-face rule to align metrics. Alternatively, font-display: optional avoids the swap altogether at the cost of occasionally showing the fallback on a first visit.

Check your setup

  1. Open DevTools, Network tab, filter by Font, and count the files and their sizes.
  2. Throttle the connection and reload to see how text behaves while fonts load.
  3. Check the layout shift entries in the Performance panel for shifts caused by font swaps.
  4. Confirm font files have a long Cache-Control lifetime.

Icon fonts: a special case

Many themes still load a full icon font to display a handful of symbols such as a menu button, a phone and a few social logos. These fonts can contain hundreds of icons, and you pay for all of them. Replace them with inline SVG for the icons you actually use. SVG icons are crisp at every size, can be styled with CSS, need no extra request when inlined, and are not hidden behind a failed font download that leaves empty squares on the screen.

Licensing and privacy

Before copying a font to your server, check its licence. Open-licensed families generally allow self-hosting, while commercial fonts often require a web licence with specific traffic or domain terms. Keep a record of where each font came from. Self-hosting also means visitor browsers do not contact a font provider at all, which simplifies the list of third parties your privacy policy has to describe.

Fonts served from your own hosting

Self-hosting fonts means they are delivered by your own site, alongside the rest of your files. On Zebra Hosting Cloud you manage the files through Plesk, with free SSL on every plan; the CDN page explains how to serve static files like fonts from locations closer to visitors.