Subsetting Cuts Font Files 60% Smaller
Font subsetting, removing glyphs you don't use from a font file, is the single highest-impact optimization for web typography. Production data across thousands of sites shows consistent file size reductions of 60-75% for typical Latin-script content, and 95%+ for strict English-only deployments. The technique has been available for over a decade but is still missing from most websites.
The Numbers
| Font | Full File | Latin Subset | English Only | Reduction |
|---|---|---|---|---|
| Inter Regular | 300 KB | 120 KB | 35 KB | 88% |
| Roboto Regular | 168 KB | 82 KB | 28 KB | 83% |
| Open Sans Regular | 217 KB | 96 KB | 31 KB | 86% |
| Noto Sans JP | 4.5 MB | N/A | 580 KB (JIS subset) | 87% |
Why Most Sites Still Don't Subset
Despite the size impact, subsetting adoption remains low. Most projects use Google Fonts (which subsets automatically server-side), but self-hosted fonts almost always ship as full multi-script files. The friction is process: most font tooling pipelines don't include a subsetting step. When designers download a font from a foundry, they get the full file with hundreds of unused glyphs.
Tools like our font subsetter and command-line pyftsubset make the process near-automatic. For per-script guidance and Unicode ranges, see our font subsetting by language guide.
CJK Fonts Benefit Most
The largest gains apply to CJK (Chinese, Japanese, Korean) fonts, where full files run 5-30 MB and contain 11,000-30,000+ glyphs. Aggressive subsetting to the most-used 2,500 characters, the Joyo Kanji list for Japanese, KS X 1001 for Korean, GB 2312 for Simplified Chinese, produces 80-95% reductions. For Mandarin sites Google's approach goes further: split fonts into ~100 unicode-range chunks of co-occurring characters, served only when the page actually contains them.
Why It Matters Now
Mobile traffic on slow networks remains 30-50% of global web users. A 200 KB font cut to 30 KB on a 3G connection saves over a second of LCP. Subsetting is one of the few free optimizations available, no extra licensing, no infrastructure changes, just a build step.
Variable Fonts Replace Static Files
Variable fonts (OpenType 1.8, 2016) consolidate an entire type family, every weight, width, and italic variant, into a single file. The performance math is decisive: a typical 6-weight family at 80 KB per static WOFF2 file totals 480 KB; the equivalent variable font runs 150-200 KB. Browser support reached 96%+ in 2023, and by 2026 there is no remaining technical reason to ship static-only stacks.
Browser Support
- Chrome 66+ (April 2018), full support
- Firefox 62+ (September 2018), full support
- Safari 11+ (September 2017), full support
- Edge 17+ (April 2018), full support
- Global usage: 96%+ as of 2026
The Five Standard Axes
| Axis | Tag | Range | CSS Property |
|---|---|---|---|
| Weight | wght | 100-900 | font-weight |
| Width | wdth | 75-125 | font-stretch |
| Italic | ital | 0-1 | font-style |
| Slant | slnt | -90 to 90 | font-style: oblique |
| Optical Size | opsz | auto / numeric | font-optical-sizing |
CSS Implementation
@font-face {
font-family: "Inter Variable";
src: url("/fonts/inter-var.woff2") format("woff2-variations");
font-weight: 100 900; /* Range, not single value */
font-style: normal;
font-display: swap;
}
/* Use any weight in the range */
.heading { font-weight: 720; }
.body { font-weight: 380; }
/* Or use named instances */
.bold { font-weight: bold; }
/* Custom axes via font-variation-settings */
.condensed-bold {
font-variation-settings: "wdth" 85, "wght" 700;
}Available Variable Versions
Most major Google Fonts ship variable versions: Inter, Roboto Flex, Open Sans, Lato, Manrope, Montserrat, Source Sans 3, Recursive, and many others. Adobe Fonts and most type foundries now release variable versions alongside static. If your current font family doesn't have one, picking a comparable variable replacement is one of the easiest ways to cut total font payload by 50%+.
You cannot programmatically convert existing static files into a variable font, the font must be designed as variable from the source. But for any project actively choosing fonts, variable versions should now be the default unless there's a specific reason not to.
Core Web Vitals & Font Loading
Fonts directly affect two of Google's Core Web Vitals: Largest Contentful Paint (LCP) and Cumulative Layout Shift (CLS). Sites passing CWV thresholds get measurable ranking benefits; sites failing are flagged in Search Console. By 2026, CWV-aware font loading is no longer optional for sites that care about organic traffic.
font-display Strategy
| Value | Behavior | Use For |
|---|---|---|
swap | Show fallback immediately, swap when web font loads | Body text, most content |
optional | Use web font only if loaded in ~100ms, else fallback only | Above-the-fold LCP text |
block | Invisible text for ~3s, then fallback | Avoid (causes FOIT) |
fallback | Brief invisible period, then fallback, swap if loads quickly | Compromise |
Preload Critical Fonts
Preload only the most critical font file, usually the body text regular weight in WOFF2. Preloading more than 1-2 fonts hurts performance by competing with other critical resources.
<!-- In <head>, before any CSS that uses the font --> <link rel="preload" href="/fonts/inter-var.woff2" as="font" type="font/woff2" crossorigin /> <!-- Don't preload fonts loaded via Google Fonts CDN --> <!-- Don't preload more than 1-2 fonts -->
CSS Metric Overrides for CLS
The most impactful CWV optimization in recent years is CSS metric overrides. When a fallback font swaps to the web font, different metrics cause text reflow and layout shift. The size-adjust,ascent-override,descent-override, andline-gap-override properties let you align fallback metrics to the web font, eliminating CLS during swap.
@font-face {
font-family: "Fallback for Inter";
src: local("Arial");
size-adjust: 107%;
ascent-override: 90%;
descent-override: 22%;
line-gap-override: 0%;
}
body {
font-family: "Inter Variable", "Fallback for Inter", sans-serif;
}Next.js automates this with next/font, calculating override values from the actual web font metrics at build time. For projects not using Next.js, tools like fontaine do the same calculation programmatically.
WOFF2 Hits 97% Browser Support
WOFF2, the Brotli-compressed evolution of WOFF, now has 97%+ global browser support. This crosses a threshold most sites have been waiting for: the WOFF and EOT fallbacks that bloated CSS for the last decade can finally be removed. The complete migration to WOFF2-only delivery is now the default recommended strategy.
Format Lineage
| Format | Status | Compression | Action |
|---|---|---|---|
| WOFF2 | Active standard | Brotli (best) | Use as primary |
| WOFF | Legacy fallback | zlib | Drop unless analytics show pre-2018 traffic |
| TTF/OTF (web) | Legacy fallback | None | Drop entirely |
| EOT | Obsolete | Custom | Remove (IE retired 2022) |
| SVG fonts | Obsolete | XML (huge) | Remove (deprecated 2018) |
Modern @font-face Syntax
The historical "bulletproof" @font-face with EOT, WOFF2, WOFF, TTF, and SVG entries is now bloat. Modern syntax is two lines:
/* Modern: WOFF2-only (2026) */
@font-face {
font-family: "Inter";
src: url("/fonts/inter.woff2") format("woff2");
font-weight: 400;
font-display: swap;
}
/* If you absolutely need fallback for pre-2018 browsers */
@font-face {
font-family: "Inter";
src:
url("/fonts/inter.woff2") format("woff2"),
url("/fonts/inter.woff") format("woff");
font-weight: 400;
font-display: swap;
}File size impact of dropping fallbacks: removing TTF entries saves 40-60 KB per font weight; removing WOFF saves another 20 KB. Across a typical 4-weight family that's 200-320 KB of unnecessary download for the small percentage of users who need it. Modern best practice is WOFF2-only with a single optional WOFF fallback only if your specific user base requires it.
Font Security: CVE-2025-27363 & FreeType
Font files are surprisingly attack-prone software. They contain complex binary data structures (glyph outlines, hinting bytecode, OpenType layout tables) that must be parsed by font rendering engines, and parsers are historically vulnerable. CVE-2025-27363, an out-of-bounds write in FreeType's TrueType glyph parsing code (CVSS 8.1), was the most consequential font-related security event in years.
What CVE-2025-27363 Was
- Vulnerability: Out-of-bounds write in FreeType's TrueType glyph parser
- Severity: CVSS 8.1 (critical)
- Impact: Arbitrary code execution when processing malicious font files
- Affected platforms: Android, Linux desktops, Chrome, server-side font tools, anything using FreeType to parse font files
- Status: Patched April 2025; was actively exploited in the wild before disclosure
How Font Files Become Malicious
Font files are mini binary programs. The TrueType bytecode interpreter that processes hinting instructions is essentially a virtual machine. Malformed glyph data, malicious hinting bytecode, or carefully crafted OpenType table corruption can trigger buffer overflows, integer overflows, or out-of-bounds writes in the parser, all of which can be weaponized into code execution.
Practical Defenses
1. Trusted Sources Only
Use fonts from Google Fonts, Adobe Fonts, or licensed foundries. These have technical review processes that catch malformed data. Never use random font files from search results or unauthorized download sites, and when downloading, use licensed sources for both security and legal reasons.
2. Re-encode Fonts
Running font files through a converter strips raw binary data and rebuilds the font from parsed glyph data. Malicious payloads that depend on specific table corruption rarely survive re-encoding. If you accept user-uploaded fonts, run them through our converter first.
3. Validate with Font Tools
Tools like Font Bakery and our font analyzer check font files for valid structure, OpenType conformance, and common red flags. They won't catch every zero-day but rule out the most obvious malformed payloads.
4. Keep Browsers and Systems Updated
Font parser vulnerabilities affect browsers (Chrome, Firefox, Safari), operating systems (Windows, macOS, Linux, Android), and document readers (Adobe Reader, Word). Patching cycles for CVE-2025-27363 took 4-6 weeks across the major platforms. For enterprise environments, automated patching is the only reliable defense.
5. Web Fonts via @font-face Are Affected Too
When a browser downloads a WOFF2 file, it uses a font parser (often a FreeType fork) to render glyphs. If the file is malformed, the parser vulnerability can be triggered in the user's browser. Browsers sandbox font rendering, but sandbox-escape chains have been demonstrated. Self-hosting from trusted sources is the practical mitigation.
The Pattern
Font parser vulnerabilities are not new, there have been multiple high-severity FreeType, DirectWrite, and Core Text vulnerabilities since 2010. CVE-2025-27363 won't be the last. The defensive posture is the same regardless of any specific CVE: only use trusted font sources, re-encode user-uploaded fonts, and keep browsers and operating systems patched.
Apply These Trends to Your Site
Convert to WOFF2, subset for your character set, switch to variable fonts, and deploy CWV-aware font loading, all in one workflow with our converter.
