Web fonts, while improving visual design, can significantly impact page load performance if not optimized correctly — this guide covers practical techniques for fast, well-behaved font loading.
Why Font Loading Affects Performance
Fonts are render-blocking resources by default in many configurations — the browser may delay showing text until the font loads (invisible text) or show a fallback then swap (potential layout shift), both affecting perceived performance and Core Web Vitals metrics.
Using font-display for Better Loading Behavior
@font-face {
font-family: 'MyFont';
src: url('/fonts/myfont.woff2') format('woff2');
font-display: swap;
font-display: swap shows fallback text immediately, then swaps to the custom font once loaded — avoids the "invisible text" problem, trading it for a visible (but generally less jarring) font swap.
Preloading Critical Fonts
<link rel="preload" href="/fonts/myfont.woff2" as="font" type="font/woff2" crossorigin>
Preloading tells the browser to fetch this critical resource earlier than it would discover it naturally through CSS parsing — particularly valuable for fonts used in above-the-fold content.
Using WOFF2 Format (Best Compression)
WOFF2 offers meaningfully better compression than older formats (WOFF, TTF, OTF) with essentially universal modern browser support — use WOFF2 as your primary format; legacy format fallbacks are rarely necessary for current browser support requirements.
Subsetting Fonts to Reduce File Size
pip install fonttools --break-system-packages
fonttools subset myfont.ttf --unicodes="U+0000-00FF" --output-file=myfont-subset.woff2 --flavor=woff2
If you only need specific character sets (Latin characters only, for example, not full Unicode coverage), subsetting removes unused glyphs, significantly reducing file size.
Self-Hosting Fonts vs Third-Party Font Services
Self-hosting fonts (rather than loading from a third-party font CDN) eliminates an additional DNS lookup/connection, and avoids sending user data to a third party — generally the better-performing and more privacy-respecting choice, at the cost of managing font files yourself.
Limiting the Number of Font Weights/Styles Loaded
Each additional font weight/style (bold, italic, various numeric weights) is a separate file to download — audit whether you genuinely need every weight you're loading; unused weights are pure waste.
Using Variable Fonts for Multiple Weights in One File
@font-face {
font-family: 'MyVariableFont';
src: url('/fonts/myfont-variable.woff2') format('woff2-variations');
font-weight: 100 900;
}
A variable font contains multiple weights/styles in a single file, often smaller in total than loading several separate static weight files — worth considering if you use multiple weights of the same font family.
Setting Long Cache Duration for Font Files
See How to Configure Browser Caching and Cache-Busting for Static Assets — fonts rarely change, so a long cache duration with cache-busting on genuine updates is appropriate, avoiding repeated downloads for returning visitors.
Common Errors
Noticeable layout shift when the custom font loads — use size-adjust or font-matching techniques to make your fallback font's metrics closer to your custom font's actual rendered size, minimizing the visual jump during swap.
Continue Reading
- How to Optimize Images for Web Performance
- How to Configure Browser Caching and Cache-Busting for Static Assets
- Understanding Core Web Vitals for Static Sites
Browse more articles in Static Site Hosting & Frontend Deployment.