How Fonts Slow Down Your Site and What to Do About It
On a high-traffic project, we noticed LCP increased by 1.2 seconds due to loading a custom font. The browser waited for Google Fonts five times (different weights), and users saw a blank screen for two whole seconds. After properly configuring font-display, preload, and subset, we reduced the time to 0.4 seconds—and CLS dropped from 0.25 to 0.01. The fix took 6 hours but paid off with a 40% improvement in Core Web Vitals.
In this article, we’ll show you how to configure fonts without losing performance. You’ll learn which font-display values to choose, how to preload critical fonts, why subsetting matters, and why self-hosting beats Google Fonts. We’ll also share real cases from our practice—over 50 projects with font optimization.
Why font-display: swap Doesn’t Solve CLS
font-display: swap shows a system font immediately, then swaps to the custom font. However, if the font hasn’t loaded within 100 ms, a re-layout occurs—CLS increases. To avoid this, you need to compensate for the metric differences between the custom and fallback fonts. Use the properties ascent-override, descent-override, line-gap-override, and size-adjust:
@font-face { font-family: 'InterFallback'; src: local('Arial'); ascent-override: 90%; descent-override: 22%; line-gap-override: 0%; size-adjust: 107%; } body { font-family: 'Inter', 'InterFallback', sans-serif; } To find precise values, use the fontaine package or the built-in Next.js next/font function—it automatically generates a fallback with correct metrics. As stated in the MDN documentation, using size-adjust achieves minimal CLS. According to Web Almanac, improper font loading increases CLS by an average of 0.15.
| Value | Behavior | When to Use |
|---|---|---|
| auto | Depends on browser | Not recommended |
| block | Hide text until loaded (FOIT) | Icon fonts |
| swap | Fallback → custom when loaded | Body text |
| fallback | 100 ms hidden, then swap | Balance FCP/CLS |
| optional | Only if already cached | Non-critical fonts |
Preload: Only Critical Files
Preloading all fonts on the page is a common mistake. The browser is forced to load 5–6 files in a competitive queue, slowing down other resources. Preload only above-the-fold fonts—for example, the regular and bold weights for headings:
<link rel="preload" href="/fonts/inter-regular.woff2" as="font" type="font/woff2" crossorigin> <link rel="preload" href="/fonts/inter-700.woff2" as="font" type="font/woff2" crossorigin> How Subsetting Reduces Font Size by 5–10×
The full Inter font includes Latin, Cyrillic, Greek, Hebrew, and weighs ~500 KB. After subsetting to only needed characters (Cyrillic + basic Latin), the size drops to 30–80 KB—savings of 5–10×. Use pyftsubset from the fonttools library:
pip install fonttools brotli pyftsubset inter-regular.ttf \ --unicodes="U+0020-007E,U+00A0-00FF,U+0400-045F,U+0490-0491" \ --layout-features="kern,liga,calt" \ --flavor=woff2 \ --output-file=inter-regular-subset.woff2 Additional: Automating Subsetting
For CI/CD, you can use the npm package `fontkit` or the built-in capabilities of Webpack/Next.js. This allows generating subsets at build time.Self-Hosted Fonts Are 200+ ms Faster Than Google Fonts
Google Fonts adds DNS lookup, TLS handshake, and cross-origin latency. Self-hosted fonts:
- Eliminate an extra request to a third-party domain
- Allow HTTP/2 push (though preload is better)
- Work even when Google is blocked (e.g., in China)
Measurements show that self-hosting on the same CDN speeds up LCP by 200–300 ms compared to Google Fonts. We recommend downloading fonts via google-webfonts-helper or installing the npm package @fontsource-variable/inter.
| Comparison | Google Fonts | Self-hosted |
|---|---|---|
| Extra DNS lookup | Yes | No |
| Cache control | Limited | Full |
| Subset capability | Via URL | Custom |
| Works when blocked | No | Yes |
What’s Included in Font Optimization Work
If you order this service from us, the result includes:
- Audit of current fonts—analysis of weight, number of styles, source (Google Fonts/self-hosted)
- Subsetting—generating subsets for Cyrillic and Latin
- Self-hosting—moving fonts to your server or CDN
- Configuring font-display—correct values for critical and non-critical fonts
- Preloading critical files—only for above-the-fold
- CLS compensation—fallback with correct metrics
- Documentation—description of all changes and maintenance recommendations
Timeline: 4 to 8 hours depending on the number of fonts and weights. The cost is calculated individually—contact us for an estimate for your project.
Our team has 10+ years of experience in web performance and certification in Google Core Web Vitals. We guarantee metric improvements: LCP will drop by at least 30%, and CLS will be below 0.1. Order font optimization with a guaranteed metric improvement. Contact us for a comprehensive site audit.







