Performance
Web Font Performance: WOFF2, font-display, and Core Web Vitals
Fonts are one of the most common causes of slow, janky page loads. They block text from rendering, trigger layout shifts when they swap in, and can add hundreds of kilobytes of download. The good news: a handful of well-known techniques eliminate almost all of the pain. Here is the practical checklist.
Use WOFF2 — and nothing older
WOFF2 is the modern web font format, with Brotli compression that makes files roughly 30% smaller than WOFF and far smaller than raw TTF/OTF. It is supported by every browser you need to care about. Serve WOFF2 only; do not ship legacy TTF or EOT fallbacks that bloat your CSS.
Control rendering with font-display
The font-display descriptor decides what the browser does while a font loads. The two values you will use most:
- `swap` — show fallback text immediately, then swap in the web font. Best for body text; guarantees content is never invisible.
- `optional` — use the web font only if it loads almost instantly; otherwise keep the fallback for this page view. Best for fonts where avoiding any layout shift matters more than the exact typeface.
@font-face {
font-family: 'Inter';
src: url('/fonts/inter.woff2') format('woff2');
font-display: swap;
}Preload your critical fonts
The font used in your headline or above-the-fold body text is on the critical path. Preload it so the browser fetches it early, in parallel with your CSS, instead of waiting to discover it:
<link rel="preload" href="/fonts/inter.woff2" as="font" type="font/woff2" crossorigin>Preload sparingly — only the one or two fonts visible on first paint. Preloading everything defeats the purpose by competing for bandwidth.
Subset to the characters you use
A full font includes glyphs for many languages and symbols you may never display. Subsetting strips it down to the characters you actually need (for example, basic Latin), often cutting file size by more than half. Google Fonts subsets automatically based on the text or language parameters; for self-hosted fonts, tools like glyphhanger or fonttools create subsets.
Eliminate layout shift with metric overrides
When a web font swaps in and it is a different size from the fallback, the text reflows — hurting your Cumulative Layout Shift (CLS) score. You can neutralize this by tuning the fallback to match the web font's metrics using the size-adjust, ascent-override, and descent-override descriptors on a fallback @font-face:
@font-face {
font-family: 'Inter Fallback';
src: local('Arial');
size-adjust: 107%;
ascent-override: 90%;
descent-override: 22%;
}
body {
font-family: 'Inter', 'Inter Fallback', sans-serif;
}Frameworks like Next.js generate these overrides automatically when you use their built-in font loaders, which is why optimized font loading is one of the easiest Core Web Vitals wins available.
The performance checklist
- Serve WOFF2 only.
- Add `font-display: swap` (or
optional) to every@font-face. - Preload the one or two above-the-fold fonts.
- Subset to the characters and languages you actually use.
- Load only the weights you render — prefer a variable font when you need three or more.
- Add metric-override fallbacks to kill layout shift.
- Self-host when you can, to avoid a third-party connection and gain caching control.
Pair these techniques with clean implementation from our CSS @font-face guide, and your typography will be both beautiful and fast.
Spotted a font you love?
Upload any image and let our AI identify the typeface in seconds — free, no sign-up.
Try the AI Font Finder