Modern font loading guide
I came across this blog post from Jono Alderson and learned a lot about how to best load modern fonts so that they do not slow down the website. And below are the notes that I took from the post:
Core fundamentals
- Use WOFF2 format only: It's the most efficient and universally supported
- Self-host fonts: Don't rely on Google Fonts or other CDNs for better performance and privacy
Loading strategy
- Set
font-display: swap: Shows fallback text immediately, then swaps when webfont loads - Preload critical fonts: Use the
rel="preload"tag as shown below<link rel="preload" as="font" type="font/woff2" crossorigin href="/fonts/font.woff2"> - Inline
@font-facedeclarations: Put them in the<head>rather than external CSS files - Design with fallbacks first: Choose system fonts that match your custom font's metrics
File optimization
- Subset fonts aggressively: Only include characters/scripts you actually need using
unicode-range - Use variable fonts strategically: Only when they're smaller than multiple static files
- Avoid legacy formats: No need for TTF, OTF, WOFF, or SVG fonts in modern browsers
- Never use icon fonts: Replace with inline SVG or SVG sprites instead
Metrics and layout stability
- Match fallback metrics: Use
size-adjust,ascent-override,descent-overrideto prevent layout shift - Use
font-size-adjust: Scale fallback fonts to match your custom font's x-height - Prevent fake bold/italic: Set
font-synthesis: noneand only declare weights you provide
System and fallbacks
- Build robust system stacks: Start with
-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto - Include emoji fonts in stack: Add system emoji fonts rather than shipping custom emoji
- Test across platforms: Different OS render fonts differently
Performance monitoring
- Set font budgets: Limit number of weights and file sizes
- Test on slow networks: Use DevTools to simulate poor conditions
- Measure layout shift: Monitor CLS caused by font loading
That's it.
By the way, I got to know about this blog post from a post on X when I was casually browsing.