Performance Guide

Font Subsetting & Web Font Optimization Guide

Reduce font file sizes by 60-90% with subsetting, unicode-range, and smart loading strategies

Stewart Celani Created Feb 14, 2026 8 min read

Quick answer: Font subsetting reduces web font file sizes by 60-90% by including only the characters your website actually uses. Combined with WOFF2 compression and font-display: swap, you can significantly improve Core Web Vitals scores.

Ready to optimize your fonts? Convert to WOFF2 for the best compression:

What is Font Subsetting?

Font subsetting is the process of removing unused characters from a font file, keeping only the glyphs your website actually needs. A typical web font like Roboto contains thousands of characters for multiple languages, but your site probably only uses a fraction of them.

When you subset a font to just the Latin characters you need, file sizes drop dramatically. Research shows Roboto Regular weighing 168KB as a TTF can be reduced to just 12KB as a subsetted WOFF2 file — a 93% reduction. Inter, a variable font, drops from 303KB to 22KB (93% reduction) with Latin-only subsetting.

Common Misconception

Unicode-range doesn't subset your font files. The unicode-range CSS descriptor controls which font files the browser downloads, but it doesn't actually reduce the file size. If your page contains any character in the range, the entire font file downloads with all its glyphs. The correct approach is to use both: physically subset the files, then use unicode-range to tell the browser which subset to load.

Character Sets and Scripts

Fonts are organized by character sets and scripts. Understanding these helps you choose what to include:

  • Basic Latin — English letters, numbers, basic punctuation (typically 12-30KB)
  • Latin Extended — Additional European characters, accented letters (adds 5-15KB)
  • Cyrillic — Russian, Bulgarian, Serbian (adds 5-15KB)
  • Greek — Greek alphabet (adds 5-15KB)
  • CJK — Chinese, Japanese, Korean (adds megabytes — avoid unless needed)

When to Subset

Subsetting makes sense when you know exactly which characters appear on your site. It's ideal for:

  • Landing pages with controlled text
  • Marketing sites with predictable content
  • Apps with limited character requirements

Avoid subsetting for user-generated content sites, forums, or anywhere users might type in multiple languages.

Unicode-Range Optimization

The unicode-range CSS property lets browsers download only the font characters they need, even from a full font file. It's like progressive loading for fonts.

How Unicode-Range Works

Instead of subsetting upfront, you serve a full font but tell the browser which codepoints it covers. The browser checks what characters are on the page and only downloads the matching portions:

@font-face {
  font-family: 'MyFont';
  src: url('myfont.woff2') format('woff2');
  unicode-range: U+0020-007F, U+00A0-00FF;
}

This example covers Basic Latin (U+0020-007F) and Latin Extended-A (U+00A0-00FF). The browser sees this range and only downloads glyphs for those characters.

Common Unicode Ranges

  • U+0020-007F — Basic Latin (English)
  • U+00A0-00FF — Latin-1 Supplement
  • U+0100-017F — Latin Extended-B
  • U+0400-04FF — Cyrillic
  • U+0370-03FF — Greek

Combining Subsetting with Unicode-Range

The most effective approach combines both techniques: subset your fonts for your primary languages, then use unicode-range to handle fallback gracefully. This gives you minimal file sizes with intelligent browser fetching.

Variable Fonts

Variable fonts pack multiple font variations (weights, widths, styles) into a single file. Instead of loading separate files for Regular, Medium, Bold, and Black, you load one file and specify properties like font-weight: 500 or font-stretch: 75%.

Break-Even Analysis

Variable fonts aren't always smaller. The break-even point is typically around 3 weights. Here's the math:

Weights UsedStatic Files TotalVariable FontWinner
1-2 weights20-40KB60-80KBStatic
3 weights60-120KB60-80KBVariable
5+ weights100-200KB+60-80KBVariable

Subsetting Variable Fonts

Subsetting variable fonts requires extra care. Using fonttools subset, you need to specify which axes to keep:

fonttools subset font.woff2 \
  --text="Hello World" \
  --output-file=subset.woff2 \
  --layout-features='*' \
  --flavor=woff2

When Variable Fonts Make Sense

Use variable fonts when you need fine-grained typographic control — multiple weights, widths, optical sizes, or slants. They're especially powerful for design systems where you want consistent typography across many components without managing dozens of font files.

Font Loading Strategies

Even optimized fonts can block page rendering. The font-display CSS property controls how browsers handle font loading, determining the trade-off between perceived load speed and visual stability.

Font-Display Values

ValueBehaviorBest For
swapShow fallback immediately, swap when loadedMost websites (recommended)
blockInvisible text until font loads (FOIT)When text must match exactly
fallbackVery short block, then fallbackBalanced approach
optionalBrowser decides (network-dependent)Performance-first sites

Recommended: font-display: swap

Use font-display: swap for most cases. Users see fallback text immediately (preventing invisible text), then the custom font swaps in once loaded. This is the best balance of perceived performance and user experience.

Preloading Critical Fonts

For above-the-fold text, consider preloading to eliminate layout shift:

<link rel="preload" 
      href="/fonts/myfont.woff2" 
      as="font" 
      type="font/woff2" 
      crossorigin>

Only preload fonts that are immediately visible. Preloading too many fonts delays other critical resources.

Self-Hosting vs Google Fonts

Both self-hosting and Google Fonts have merits. The right choice depends on your site's traffic patterns, update frequency, and performance requirements.

Self-Hosting Benefits

  • Full control — Subset, compress, and optimize exactly as needed
  • No third-party requests — Eliminates DNS lookups and connection setup
  • Better cache behavior — Long-term caching with your version control
  • Privacy — No requests to Google servers

When Google Fonts Makes Sense

  • Rapid prototyping — Quick iteration without build steps
  • Large font libraries — Access to 1,400+ families easily
  • Automatic updates — Fonts stay current without manual work
  • Simple sites — Blogs or landing pages with minimal customization

Google Fonts with Self-Hosting

A hybrid approach works well: download Google Fonts and self-host the subsetted versions. You get the selection convenience with the performance benefits of self-hosting.

Real-World Benchmarks

Here's what actual font optimization looks like in practice, using common open-source fonts:

FontOriginal (TTF)WOFF2Latin SubsetTotal Savings
Roboto Regular168KB53KB (68%)12KB93%
Open Sans215KB68KB (68%)18KB92%
Inter303KB95KB (69%)22KB93%

These savings add up quickly across a site. To convert your fonts to WOFF2 for the best compression, use our TTF to WOFF2 converter or OTF to WOFF2 converter.

Tools for Measuring

  • Lighthouse — Core Web Vitals, including font load performance
  • WebPageTest — Waterfall charts showing font download timing
  • Chrome DevTools — Network tab with font file sizes
  • FontTools — CLI for subsetting (pip install fonttools)

Licensing Considerations

Not all fonts can be legally subset. Many commercial licenses prohibit modification of the font file, including subsetting. The SIL Open Font License (OFL) permits subsetting but treats the result as a "Modified Version" — if the font has a Reserved Font Name, subsets must be renamed. Always check the EULA before subsetting.

Frequently Asked Questions

Does font subsetting affect quality?

No. Subsetting only removes glyphs — it doesn't alter the remaining characters. The font renders identically; it simply contains fewer characters. There's no quality loss.

How much smaller are WOFF2 fonts compared to TTF?

WOFF2 uses Brotli compression, achieving 60-70% smaller files compared to uncompressed TTF. A 168KB Roboto TTF becomes 53KB as WOFF2. Combined with subsetting, you can reach 90%+ reduction.

Should I use font-display: swap for all fonts?

Yes, for most cases. The swap value prevents invisible text (FOIT) by showing fallback fonts immediately, then swapping to your custom font once loaded. This is the best balance for user experience and perceived performance.

What's the break-even point for variable fonts?

Variable fonts typically break even around 3 weights. Below that, individual static font files are smaller. Above 3 weights, the single variable font file becomes more efficient. Most design systems benefit from variable fonts.

Can I subset fonts with user-generated content?

Subsetting isn't recommended for sites with user-generated content where you can't predict what characters users will type. Instead, use unicode-range to let browsers fetch only needed characters from a full font, or accept larger font files.

Does unicode-range automatically subset my font files?

No. Unicode-range controls loading behavior, not file contents. If you set unicode-range but serve a full font file, browsers will still download the entire file — it just won't use it for characters outside the range. You must physically subset the font file and use unicode-range together for optimal performance.

Convert.FAST converts fonts to WOFF2 for the best compression. All conversions run on encrypted EU servers and auto-delete after 1 hour.

Stewart Celani

Stewart Celani

Founder

15+ years in enterprise infrastructure and web development. Stewart built Tools.FAST after repeatedly hitting the same problem at work: bulk file processing felt either slow, unreliable, or unsafe. Convert.FAST is the tool he wished existed—now available for anyone who needs to get through real workloads, quickly and safely.

Read more about Stewart