Key takeaways
- Use fewer fonts: one or two families, only the weights you actually use, ideally as variable fonts.
- Always use
font-display: swapso text shows immediately in a fallback font. - Self-hosting WOFF2 files and preloading the main one is usually the fastest option.
Typography shapes how a brand feels — but every font file is a download that can delay text, shift layouts and add third-party requests. I’ve seen WordPress sites loading 12 font files from three different services. Here’s how to get the look you want while keeping pages fast.
How web fonts affect performance#
- Invisible text (FOIT): by default some browsers hide text up to 3 seconds while the font loads.
- Layout shift: when the web font replaces the fallback, differences in size move text around (CLS).
- Extra connections: Google Fonts needs two origins (fonts.googleapis.com for CSS, fonts.gstatic.com for files).
- Weight: each weight and style is a separate file (20–100 KB each).
Step 1: choose fewer fonts#
- One family for body text, optionally one for headings.
- Only the weights you use — typically 400, 600 and 700.
- Consider variable fonts: one file covers all weights.
- Or use a system font stack for body text — zero downloads:
font-family: system-ui, -apple-system, "Segoe UI", Roboto, Arial, sans-serif;
Step 2: font-display#
@font-face {
font-family: "Inter";
src: url("/fonts/inter-var.woff2") format("woff2");
font-weight: 100 900;
font-display: swap;
}
swap shows text in a fallback immediately and swaps in the web font when ready. With Google Fonts, add &display=swap to the URL (most themes do).
Step 3: Google Fonts vs self-hosting#
| Google Fonts CDN | Self-hosted | |
|---|---|---|
| Setup | One link tag | Download WOFF2 files, write @font-face |
| Speed | Extra DNS/TLS to two origins; no shared cache benefit anymore | Same origin as your site; can be preloaded |
| Privacy | Visitor IPs sent to Google (a GDPR concern in the EU) | No third-party requests |
| Updates | Automatic | Manual |
Browsers no longer share cached fonts between websites, so the old “everyone already has it cached” argument for Google Fonts is gone. If you stay with Google Fonts, add preconnect hints:
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
Need a hand with this?
Get a quick, honest review of your website’s SEO.
Step 4: preload the critical font#
<link rel="preload" href="/fonts/inter-var.woff2" as="font" type="font/woff2" crossorigin>
Preload only the one or two fonts used above the fold. Preloading everything competes with your LCP image.
Step 5: reduce layout shift from font swapping#
@font-face {
font-family: "Inter Fallback";
src: local("Arial");
size-adjust: 107%;
ascent-override: 90%;
}
body { font-family: "Inter", "Inter Fallback", sans-serif; }
Adjusting the fallback’s metrics makes the swap nearly invisible. Tools like Fontaine or Next.js’s font system calculate these values automatically.
Step 6: subset fonts#
Most sites only need Latin characters. Subsetting removes unused glyphs (Cyrillic, Greek, Vietnamese) and can cut file size by more than half. Google Fonts serves subsets automatically via unicode-range. For Hindi or Marathi content, include the Devanagari subset.
WordPress tips#
- Check how many fonts your theme, page builder and plugins load (DevTools → Network → Font).
- Disable duplicate Google Fonts loading from page builders if your theme already loads them.
- Plugins like OMGF or performance plugins can self-host Google Fonts automatically.
- Block themes let you register local fonts via
theme.json.
Web fonts FAQ#
Is WOFF2 enough?#
Yes. All modern browsers support WOFF2, the most compressed web font format.
Do icon fonts hurt performance?#
Icon fonts like Font Awesome often load hundreds of unused icons. Inline SVG icons are lighter and more accessible.
Will changing fonts affect SEO?#
Not directly. Faster, more readable text improves user experience and Core Web Vitals.