Web Font Loading and Performance: The Complete Guide
Eliminate FOUT, FOIT, and layout shifts from web fonts. Loading strategies, subsetting, and font-display options explained.
- Eliminate FOUT, FOIT, and layout shifts from web fonts.
- Why Web Fonts Cause Performance Issues.
- Font Loading Strategies.
- Subsetting and Self-Hosting.
- The font-display Property.
Why Web Fonts Cause Performance Issues
Web fonts are one of the most common causes of poor LCP scores and CLS. When a page loads, the browser discovers fonts only after parsing CSS, creating a waterfall: HTML → CSS → Font request. During this delay, text is either invisible (FOIT — Flash of Invisible Text) or shown in a fallback then swapped (FOUT — Flash of Unstyled Text), causing layout shift. Each font weight is a separate download. A typical setup with regular, italic, bold, and bold italic across two families means 8 files — potentially 200–500KB blocking text rendering.
Font Loading Strategies
For best performance: preload your critical font with link rel="preload" as="font" crossorigin, use font-display: swap to show fallback immediately, and subset to only needed characters. For best visual stability: use font-display: optional (shows fallback if font doesn’t load within 100ms — no swap, no shift) and match fallback metrics closely. For best of both: use a variable font (one file for all weights) with preload and optional display.
Subsetting and Self-Hosting
Subsetting removes unused characters. A full font like Inter has 2,500+ glyphs. English needs ~200. Subsetting can reduce 90KB to 15KB. Google Fonts does this automatically. For self-hosted fonts, use pyftsubset or Fonttools. Self-hosting eliminates DNS lookups to fonts.googleapis.com, avoids GDPR concerns, and gives full caching control. Copy the WOFF2 files, write @font-face rules, and serve from your domain. Use the Google Fonts Explorer to find and preview fonts before downloading.
The font-display Property
The font-display property controls swap behavior. ‘swap’ shows fallback immediately, swaps when font loads — visible shift. ‘optional’ gives 100ms; if missed, fallback for entire visit — zero CLS. ‘fallback’ is between them. ‘block’ hides text until font loads (avoid). For most sites, ‘swap’ with matched fallback metrics or ‘optional’ for performance-critical pages is the best choice.
Frequently Asked Questions
What is FOUT?
Should I use Google Fonts or self-host?
How many font files should a page load?
Use the Google Fonts Explorer — free, no signup required.
⚡ Open Google Fonts Explorer