
If your text flashes, disappears for a second, or arrives late, your web fonts are the likely cause. This guide shows you why custom fonts block rendering and how to fix it. You will learn how to keep text visible, cut download weight, and load the right file at the right time.
Why web fonts slow pages down
A custom font is an extra file the browser must fetch before it can paint styled text. Until that file arrives, the browser has to decide what to do with the words on the page. That decision is the root of most font performance problems.
FOIT vs FOUT
There are two behaviors. FOIT (Flash of Invisible Text) hides text until the font loads. The reader stares at a blank space. FOUT (Flash of Unstyled Text) shows a fallback font first, then swaps to the custom one. The reader sees a visual jump, but never loses the content.
FOUT is almost always the better trade. Reading a plain fallback for 200ms beats staring at nothing. You control this with the font-display descriptor.
The weight problem
Fonts are heavy. A full family with four weights and italics can add several hundred kilobytes. Most of that is characters and language ranges you never use. Downloading Cyrillic and Vietnamese glyphs for an English-only site is pure waste.
How to fix it
Set font-display: swap
Add font-display: swap; to every @font-face rule. This tells the browser to show a fallback immediately and swap when the custom font is ready. Text is never invisible. For fonts where a late swap would be jarring, optional is stricter: it uses the custom font only if it loads almost instantly, otherwise it sticks with the fallback for that visit.
Subset the file
Strip out characters you do not need. If your site is English, keep the Latin range and drop the rest. Subsetting often cuts a font file by half or more. Tools like the open-source glyphhanger, or the subset options in Google Fonts, do this for you.
Preload the critical font
Preload only the one or two font files used above the fold, such as your body weight and your main heading weight. A preload hint tells the browser to fetch the file early instead of waiting to discover it in CSS. Preloading everything defeats the purpose, because it forces low-priority fonts to compete with critical ones.
Prefer WOFF2 and a variable font
WOFF2 is the smallest widely supported format. Serve it first. If you need several weights, a single variable font file can replace four or five static files and usually weighs less overall.
A real scenario
A marketing site loaded a four-weight family plus icon glyphs, roughly 320KB, with no font-display set. On a mid-range phone the headline stayed blank for nearly a second on first visit. The fix was three changes: switch to WOFF2, subset to Latin, and add font-display: swap with a preload on the body weight. The file dropped to about 90KB, and the headline appeared instantly in a fallback, then refined. No blank text, no code rewrite.
Common mistakes and how to fix them
- Leaving font-display unset. The default is a blocking behavior close to FOIT. Always declare
swaporoptional. - Loading every weight. Audit which weights you actually use. Two is usually enough. Remove the rest.
- Preloading all fonts. This creates a traffic jam. Preload only above-the-fold files.
- Ignoring the fallback stack. Pick a fallback with similar metrics to your custom font so the swap does not shift layout. The
size-adjustdescriptor can align them. - Hosting from a third party you do not need. Self-hosting removes an extra connection to another domain and gives you control over caching.
Action checklist
- Serve WOFF2, ideally a variable font.
- Subset to the character ranges you use.
- Add
font-display: swapto every @font-face. - Preload only critical above-the-fold fonts.
- Trim unused weights and styles.
- Match your fallback stack to reduce the swap jump.
- Re-test on a real mid-range phone, not just desktop.
Conclusion and next step
Fonts feel like a design detail, but they are a performance decision. Your next step: open your CSS, find every @font-face rule, and confirm each one has font-display set and points to a subsetted WOFF2. That single pass fixes most font-related delays.
FAQ
Is system font stack always faster than a custom font?
Yes, because system fonts need no download. If brand identity does not depend on a specific typeface, a system stack is the fastest option. Use custom fonts when the visual identity justifies the cost.
Does self-hosting beat Google Fonts?
Often, yes. Self-hosting removes a connection to a separate domain and lets you control caching and subsetting. Google Fonts is convenient and still fast, but you trade some control.
Will font-display: swap cause layout shift?
It can, if the fallback and custom font have different widths. Reduce this by choosing a close fallback and using the size-adjust and ascent-override descriptors to match metrics.
How many font files should I load?
As few as possible. A single variable font covering your weights is ideal. Two static files is a reasonable ceiling for most sites.
References
- MDN Web Docs — font-display and @font-face documentation.
- web.dev — guidance on optimizing web fonts and Core Web Vitals.