Licenses

How Much Are Your Fonts Costing Your Page Speed?

· 3 min read

After images, fonts are usually the heaviest thing a page downloads — and unlike images they block what the reader sees, because text cannot be drawn until the browser knows what to draw it in. Four decisions account for nearly all of the cost. Three of them cost nothing to get right.

One: the format

A WOFF2 is around 60% smaller than the .ttf it was made from, and every browser still receiving security updates reads it. If you are serving anything else, this is a free saving and it takes one conversion. Old snippets listing EOT, SVG and TTF fallbacks are shipping files nothing requests — see the format guide.

Two: the character set

This is the big one and the one almost nobody does. A font carrying Cyrillic and Greek makes an English-language site download two alphabets it will never draw. Cutting to Latin commonly halves the file and sometimes takes three quarters off it. Every font page here offers both, with the measured sizes on the buttons, and the subsetting post explains what is being removed.

Three: how many files

Four static weights is four downloads. The same family as a variable font is one file that is usually smaller than three of those four — which is why a variable font is a performance decision and not only a design one, as long as you actually use more than two weights. If you use exactly one weight, a static file is smaller.

The other half of this is discipline. Two families is a reasonable ceiling for most sites. Three is a decision to justify. A page loading five is usually a page where nobody has looked at the network tab.

Four: when the download starts

A font referenced from a stylesheet is not requested until the browser has parsed that stylesheet, which is already late. A rel="preload" as="font" crossorigin link in the head starts it in parallel instead. Preload only what is on the first screen — preloading everything makes the page slower, because the requests compete with each other.

Then decide what the reader sees in the meantime. font-display: swap shows fallback text immediately and swaps, at the cost of a visible shift. font-display: optional gives the font a very short window and gives up for that page view if it misses, so nothing ever shifts.

The layout shift nobody attributes to fonts

When the real font swaps in, every line of text re-measures. If the fallback is much narrower or wider, the page jumps — and Cumulative Layout Shift is a ranking signal, so this is not only an aesthetic problem.

The fix is to make the fallback closer in metrics to the real font, using size-adjust, ascent-override and descent-override on an @font-face rule that points at a local system font. It is fiddly and it is the difference between a visible jump and none.

A realistic target

  1. WOFF2 only. Delete every other format from your CSS.
  2. Latin cut unless you genuinely set another alphabet.
  3. One variable file, or two static weights. Not six.
  4. Preload what is above the fold, and nothing else.
  5. Set font-display deliberately rather than leaving it to the default.

Done properly, a page with one variable family in a Latin cut is spending somewhere between 20 and 60 KB on typography. Done carelessly, the same design costs half a megabyte. The design is identical either way, which is what makes this worth twenty minutes.

Questions

How much should fonts weigh on a web page?
One variable family, served as WOFF2 and cut to the alphabet you actually use, typically lands between 20 and 60 KB. The same design served as full-coverage TTFs across four static weights can cost half a megabyte. The visible result is the same; the difference is entirely in how the files were prepared.
Do fonts slow down a website?
They can, in two ways: the bytes themselves, and the delay before text can be drawn. The bytes are fixed by format and subsetting. The delay is controlled by preloading the file and choosing a font-display value deliberately rather than accepting the default.
Are variable fonts better for performance?
If you use three or more weights, almost always — one variable file is usually smaller than three static ones and is a single request. If you use exactly one weight, a static file for that weight is smaller. The break-even is around two weights.
What causes layout shift when a font loads?
The fallback font and the real font measure differently, so every line re-flows at the moment of the swap. Matching the fallback more closely with size-adjust, ascent-override and descent-override removes most of it, and font-display: optional removes it entirely at the cost of sometimes not showing the font at all.

Fonts in this post

  • Inter

    Sans-serif · Rasmus Andersson · Variable

  • Roboto

    Sans-serif · Christian Robertson, ParaType, Font Bureau · Variable

  • Lora

    Serif · Cyreal · Variable

  • JetBrains Mono

    Monospace · Philipp Nurullin, Konstantin Bulenkov · Variable