Fonts are often the last thing developers optimize and the first thing users notice. A page can have perfect images, minimal JavaScript, and still feel slow because the browser is blocked waiting for a 300 KB font file. Here is a practical checklist that fixes most of it.
1. Serve WOFF2, and only WOFF2 if you can
WOFF2 compresses roughly 30% better than WOFF. Unless you need to support truly ancient browsers, shipping a single WOFF2 file per weight is the simplest win. Drop the TTF, EOT, and SVG versions from your font stack — they are dead weight in 2026.
2. Use font-display: swap
Without it, browsers hide text until the font loads (FOIT) or show nothing at all for seconds. Add one line to your @font-face:
@font-face {
font-family: 'MyFont';
src: url('/fonts/myfont.woff2') format('woff2');
font-display: swap;
}
Swap shows fallback text immediately and swaps in the real font when it arrives. Users read instantly; the layout shift is a fair trade and can be reduced with size-adjust (see below).
3. Preload only the fonts above the fold
Preload tells the browser to fetch a font early instead of discovering it late in the CSS cascade. Only preload the one or two weights actually used in the hero section:
<link rel="preload" href="/fonts/myfont.woff2" as="font" type="font/woff2" crossorigin>
Preloading every weight defeats the purpose — it competes with your critical resources.
4. Subset your fonts
Most fonts ship with glyphs for languages your page never uses. Subsetting keeps only the character ranges you need (e.g. latin) and can cut a font file by half or more. Tools like glyphhanger or fonttools make this a one-command job, and it is worth doing for every font you self-host.
5. Reduce layout shift with size-adjust
The classic complaint about font-display: swap is the visible jump when the webfont replaces the fallback. The size-adjust descriptor lets you scale the fallback font to match the webfont's metrics, so the swap is nearly invisible:
@font-face {
font-family: 'Fallback';
src: local('Arial');
size-adjust: 105%;
}
6. Self-host instead of hot-linking
Self-hosting removes a third-party round trip and gives you full control over caching headers. Set a long cache lifetime (a year is standard) with immutable, since font files are versioned by filename.
Where to get fonts
If you are looking for free fonts to test all of this with, FontHubs offers free downloadable font families you can self-host and subset. Pick one family, run through the checklist above, and measure the before/after in Lighthouse — the difference is usually obvious on the first run.
Checklist
- WOFF2 only
- font-display: swap
- Preload hero fonts only
- Subset to the ranges you use
- size-adjust the fallback
- Self-host with long caching
Do these six and fonts stop being a performance problem.
Top comments (0)