Fonts are one of the most overlooked speed problems on the web. Nobody thinks of their typeface as a performance issue. But when a site loads six font weights across every page, and the actual design only uses two of them, that is 200-400 KB of dead weight on every single page load.
I see this on nearly every site audit I run. A designer picks a beautiful typeface, the builder enables every available weight "just in case," and the CMS dutifully loads all of them on every page. Regular, medium, semibold, bold, italic, bold italic. Each weight is a separate file download. Each one delays rendering. And on most pages, only regular and bold are actually used in the CSS.
The real cost of unused font weights
A single font weight file is typically 30-80 KB (for WOFF2 format, which is the standard). Loading six weights means 180-480 KB of font files per page. That adds up:
- Additional network requests that compete with critical resources
- Delayed initial render while the browser downloads fonts it may never use
- CLS (Cumulative Layout Shift) when the browser swaps from a fallback font to the custom font after it loads
- Wasted bandwidth for mobile users on limited data plans
The fix is not switching to a system font or giving up on typography. The fix is being deliberate about which weights you load and how you load them.
Step 1: audit which weights you actually use
Open your site in the browser. Inspect the CSS. Search for every font-weight declaration. Write down which values appear: 400 (regular), 500 (medium), 600 (semibold), 700 (bold), and so on.
Then compare that list to which font weights your site actually loads. In Webflow, this is visible in the font settings. In WordPress, check your theme's font loading or the Google Fonts embed link in the page source.
The gap between "loaded" and "used" is your waste. Most sites load 5-6 weights and use 2-3.
Step 2: remove unused weights
In Webflow, go to your project fonts and deselect the weights you are not using. If you are using Google Fonts, update the embed URL to only request the weights you need.
In WordPress, this depends on your theme and font plugin. Some themes load fonts from Google Fonts via a URL like:
fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700;800
Each weight in that URL is a file request. Trim it to only what you use:
fonts.googleapis.com/css2?family=Inter:wght@400;700
That single change can cut font download time by 60-70%.
Want a website that turns visitors into customers, not just compliments?
Book a 15-min introStep 3: set font-display to swap
The font-display property controls what happens while custom fonts are loading. The default behavior on some browsers is to show invisible text until the font finishes downloading. This is called the "Flash of Invisible Text" (FOIT). Visitors see a blank page where text should be.
Setting font-display: swap tells the browser to immediately render text in a fallback system font, then swap to the custom font once it finishes loading. The text is always visible. The only trade-off is a brief visual shift when the swap happens.
If you are using Google Fonts, add &display=swap to the URL. If you are self-hosting, add font-display: swap to each @font-face declaration in your CSS.
This eliminates invisible text completely and improves both perceived speed and LCP scores.
Step 4: preload critical fonts
For the most important font weight (usually the body text regular weight), you can tell the browser to start downloading it immediately using a preload link in the HTML head:
<link rel="preload" href="/fonts/inter-regular.woff2" as="font" type="font/woff2" crossorigin>
This gives the browser a head start on downloading the font before it even encounters the CSS that references it. The result is earlier text rendering and reduced layout shift.
Only preload 1-2 critical font files. Preloading everything defeats the purpose and competes with other critical resources like your hero image.
Step 5: consider self-hosting
Loading fonts from Google Fonts requires a DNS lookup to fonts.googleapis.com, then a request for the CSS file, then requests for each font file. That is multiple network round-trips before a single character renders.
Self-hosting your fonts (downloading the WOFF2 files and serving them from your own domain) eliminates the DNS lookup and reduces the request chain. The browser fetches fonts from the same server as your HTML and CSS, which is faster.
Self-hosting also gives you full control over caching headers, loading behavior, and which weights are served. Google Fonts may serve different files based on the user's browser, which is helpful but unpredictable.
For Webflow, you can upload custom fonts directly. This effectively self-hosts them on Webflow's CDN. For WordPress and custom sites, download the WOFF2 files and reference them in your CSS with @font-face declarations.
CLS from font swapping
Even with font-display: swap, you may see some layout shift when the custom font replaces the fallback font. This happens because the custom font and the fallback font have different metrics: different character widths, line heights, and letter spacing. When the swap happens, text reflows and elements shift.
To minimize this:
- Choose a fallback font that closely matches your custom font's metrics. For example, if you use Inter, set the fallback to a system sans-serif that has similar proportions.
- Use CSS
size-adjustandascent-overrideproperties to fine-tune the fallback font's metrics to match the custom font. This reduces the shift when the swap occurs. - Apply fixed heights or min-heights to text containers where layout stability matters (like hero sections and navigation).
CLS from fonts is usually small (0.01-0.05), but on sites where the hero text is the largest element, even a small shift can affect the CLS score. It is worth testing.
The font loading checklist
Here is the sequence I follow on every project:
- Audit which font weights the CSS actually uses.
- Remove every weight that is loaded but not used.
- Set
font-display: swapon all@font-facedeclarations. - Preload the primary body font weight.
- Consider self-hosting for faster delivery and more control.
- Test CLS in Chrome DevTools to ensure the font swap does not cause visible layout shift.
This process typically saves 100-300 KB per page and eliminates invisible text during loading. It is one of the lower-effort, higher-impact speed optimizations available, and it is almost always overlooked because nobody thinks of fonts as a speed problem until they measure it.
If your site's font loading is contributing to slow scores and layout shift, that is part of the speed and performance audit I run before any visual changes. Fonts are a quick win that compounds across every page.