
Stop Switching to Variable Fonts (The Case for Highly-Optimized Static Subsets)
Variable fonts promise a single-file solution for typography, but their massive unoptimized payloads often create a performance bottleneck that traditional static subsets avoid.
I distinctly remember the first time I loaded Inter Variable into a project. One file! Every weight from 100 to 900! I felt like a productivity god—no more juggling six different .woff2 files for a single font family. Then I actually looked at the Network tab. My "optimized" typography solution was a 290KB blob sitting right in the critical path, holding my Largest Contentful Paint (LCP) hostage while the browser tried to parse the entire Latin Extended character set and every possible font axis.
The industry has spent the last few years treating variable fonts like the "Holy Grail" of web typography. But for most marketing sites and blogs, switching to a variable font is actually a performance regression.
Here is why you should probably stick to (highly-optimized) static subsets instead.
The "One File" Fallacy
The pitch for variable fonts is simple: instead of downloading bold.woff2, regular.woff2, and italic.woff2, you download one file that can "morph" into any weight or slant.
The problem is the girth. A variable font carries the mathematical instructions for every interpolation point along its axes. Even if you only use font-weight: 400 and 700, you are paying the "weight tax" for 100, 200, 300, 500, 600, 800, and 900.
Compare these payloads for a typical typeface:
* Variable Font (Full): ~250KB - 350KB
* Static Subset (Regular + Bold, Latin only): ~30KB - 45KB
In the world of web performance, 200KB of blocking resources is the difference between a snappy "instant" feel and a user bouncing because your headline took three seconds to stop being invisible.
The Magic of Aggressive Subsetting
The real secret to lightning-fast typography isn't variable axes; it's glyph stripping. Most font files are packed with characters you will never use—currency symbols for countries you don't serve, advanced ligatures, and glyphs for languages your site isn't even translated into.
By using static subsets, you can use tools like glyphhanger or pyftsubset to create a "micro-font."
How to strip a font to its bones
If you have a .ttf or .otf file, don't just convert it to WOFF2 and call it a day. Use a tool to remove the junk. Here is how I do it using the glyphhanger CLI:
# Install glyphhanger (requires fonttools and brotli)
npm install -g glyphhanger
# Create a subset that only includes basic Latin characters
glyphhanger --whitelist="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789!@#$%^&*()-_=+" --formats=woff2 --css YourFont-Bold.ttfThis takes your massive source file and spits out a WOFF2 that is often 80% smaller. You can't really do this with variable fonts without "pinning" axes, which defeats the whole purpose of them being variable in the first place.
The "Faux Variable" CSS Strategy
"But I want my design to look perfect!" I hear you. The irony is that you can simulate the flexibility of variable fonts by being smart with your static declarations.
If you subset your fonts correctly, you can load four different weights for the cost of half a single variable font file.
/* Optimized Static Loading */
@font-face {
font-family: 'BrandFont';
src: url('/fonts/brand-regular-subset.woff2') format('woff2');
font-weight: 400;
font-style: normal;
font-display: swap; /* Don't hide the text! */
unicode-range: U+000-00FF; /* Only load for basic Latin */
}
@font-face {
font-family: 'BrandFont';
src: url('/fonts/brand-bold-subset.woff2') format('woff2');
font-weight: 700;
font-style: normal;
font-display: swap;
unicode-range: U+000-00FF;
}By using the unicode-range property, you’re telling the browser: "Don't even think about downloading this bold font until you see a character that actually needs it."
When Variable Fonts Actually Make Sense
I’m not a total hater. Variable fonts are incredible for specific use cases:
1. High-Fidelity Animations: If you are animating font-weight or font-stretch on hover or scroll, static fonts will flicker. Variable fonts are smooth as butter.
2. Dashboard/App Contexts: If your app is 5MB of JavaScript anyway, a 200KB font file is a drop in the bucket compared to the benefit of having total typographic control.
3. Complex Internationalization: If you need to support 40 different languages on one page, a variable font with a smart loading strategy might actually be easier to manage than 50 different static subsets.
The Performance Verdict
If you’re building a content-heavy site, a blog, or a landing page, variable fonts are usually overkill.
We've been conditioned to think "Newer = Better Performance," but the math doesn't check out here. A 15KB static subset will beat a 300KB variable font every single time.
Stop downloading the whole toolbox when you just need a hammer. Your LCP (and your users) will thank you.
