Why font choices matter for page performance
Fonts influence both network transfer and client CPU work. A heavy font file increases bytes sent to the browser. Large font families with many static files create multiple requests. Rendering complex glyph outlines and layout features increases CPU usage on the device. Those two effects combine to slow time to first meaningful paint and to increase energy use on client devices, especially under constrained networks and on low powered hardware.
Primary performance vectors to watch
Network bytes and number of font files. Each extra font file is an extra request and extra kilobytes to download. Rendering CPU and layout cost. Complex fonts or many fallback switches force the browser to do more work. Render blocking. Depending on how fonts are loaded, the browser may delay text rendering while waiting for a font, or it may render fallback text then reflow when the font arrives. Both outcomes affect perceived speed.
What WOFF2 and variable fonts change
WOFF2 is a modern compressed font container widely supported by current browsers. In most cases WOFF2 files are smaller than their TTF or WOFF predecessors for the same glyph set and layout data. That size reduction reduces network transfer and often improves start render times.
Variable fonts consolidate multiple related styles into a single file. Where a brand uses many weights and italics, a single variable font can replace several static files. That reduces requests and can lower combined bytes, while allowing fine grained style selection through CSS. Variable fonts also expose axes such as weight width and slant that let you tune appearance without shipping multiple files.
Tradeoffs to consider
Variable fonts are not always smaller than an optimized subset of static files. For families with few styles variable fonts are often efficient. For families with many conditional OpenType tables or large glyph counts a variable file can still be large. WOFF2 reduces on disk size but does not change the complexity of glyph outlines that the browser must rasterize. Subsetting remains essential when the character set used on the page is smaller than the full font.
Subsetting strategies that actually work
Subsetting removes unused glyphs and layout tables from a font file. The simplest successful strategy is to tailor subsets to the language and to the critical content of a page. For example a marketing landing page in English rarely needs a full font that includes extended Cyrillic or CJK glyphs. Subsetting those scripts away reduces size substantially.
Decide which level of granularity fits your project. Application wide subsets work well for single language sites. Per page or per route subsets make sense when a site serves many languages or when a few pages require unique glyphs such as product names with special characters.
When not to subset aggressively
Do not aggressively subset interactive UI fonts where dynamic text or pasted user content may require unexpected glyphs. Also avoid subsetting CJK fonts unless you have a robust pipeline for generating and caching large subsets because CJK glyph counts make small subsets impractical. When in doubt prefer system font stacks for supporting broad multilingual coverage and use custom web fonts only for headings or brand text where typographic consistency matters most.
Practical subsetting workflow
The following workflow is a reliable starting point for integrating subsetting into a build pipeline. The examples use fonttools pyftsubset which is widely used and supports WOFF2 output.
- Collect the source font files Include the full family master files such as TTF or OTF files used by your designers.
- Identify required glyphs or Unicode ranges Decide whether to subset by Unicode ranges for a language or by an explicit glyph list for brand characters. For simple language subsets the Unicode range approach is easiest.
- Run pyftsubset to create a subset Example command to create a WOFF2 subset for Basic Latin and Latin supplement characters:
pyftsubset input-font.ttf –output-file=subset.woff2 –flavor=woff2 –unicodes=U+0000-00FF –layout-features=’*’ –glyph-names –symbol-cmap
- Test the subset locally Verify layout features such as ligatures and diacritics render correctly in target browsers. Include font feature testing across weight and style combinations you plan to use.
- Automate creation and cache the results Generate subsets during your CI build and store them in your asset pipeline or on the CDN. For per route subsets, make them part of the route build so the correct subset is deployed with that page.
- Serve as WOFF2 and provide fallbacks Use the WOFF2 file for supported browsers and serve a WOFF or TTF fallback for legacy clients if necessary. Many build tools and CDNs can negotiate correct formats based on Accept headers.
Notes on the command options
The –unicodes option accepts Unicode ranges and codepoints. The –glyphs option is an alternative when you want to include an explicit list of glyph names. The –layout-features option controls OpenType features to keep. Keeping all layout features is safe but may include data you do not need. Tailor this to preserve ligatures or contextual alternates that the brand requires.
Variable fonts and subsetting together
You can subset a variable font, but be deliberate. When you subset a variable font you can reduce glyphs and some tables while keeping the variation tables that define axes. If you only use a narrow range of an axis such as 400 to 600 weight you may be able to remove interpolation items outside that range, but that gets complex and not all tools support safe pruning of variation data. A pragmatic rule is to subset variable fonts by glyph coverage while keeping the variation axes intact unless you have a font engineering resource who can produce smaller variable masters.
Font loading and render strategies that reduce perceived delay
Preload the most important font file: add a preload link for the single font resource that affects your largest visible text such as your hero heading. When preloading include the correct resource type and mark the request as cross origin when applicable. Use the font display CSS property to control fallback behavior. The font display swap value shows fallback text immediately then swaps to the custom font when it loads. The font display optional value lets the browser skip swapping if the font arrival is slow which can avoid layout shifts on slow networks.
Balance visual consistency with speed. For critical branding elements consider an inline SVG or system font rendering for the initial paint then swap to the custom font in non layout shifting contexts. Avoid patterns where text content is invisible for long periods because that harms both accessibility and perceived performance.
Common pitfalls and how to avoid them
- Subsetting too narrowly and then causing blank glyphs or missing diacritics. Validate subsets with real content before deploying.
- Serving one subset across a multilingual site. Instead generate language targeted subsets or rely on system fonts for languages you do not control.
- Not using WOFF2 where supported. WOFF2 reduces payload and should be the primary delivery format for modern browsers.
- Using too many small font files. When many tiny font files are loaded, connection overhead can negate savings. Consolidate styles when possible using variable fonts or combined subsets.
Measuring impact and estimating emissions relevance
Measurement focuses on bytes transferred, request count, and client CPU work during layout and raster. Use network tools in your browser and a lab runner such as WebPageTest or Lighthouse to capture resource sizes and loading timelines. Compare full family files with WOFF2 subsets to quantify bytes saved and observe changes to metrics such as first meaningful paint and largest contentful paint.
The relationship to emissions follows from reduced network transfer and reduced client CPU. Fewer bytes and lower CPU overhead typically reduce energy use on devices and on network infrastructure. To make a defensible claim about emissions, pair payload and CPU measurements with a transparent methodology and avoid publishing unsupported numeric estimates. Start with relative improvements such as percent reduction in bytes and improvements to LCP and use those as the basis for further analysis if needed.
Integration into CI and CDN
Make subsetting a build step. Generate subsets once and upload them to your CDN with long cache lifetimes and immutable filenames. For per route subsets, include a manifest that maps routes to subset files. Use content negotiation or a small font serving script only when you must support legacy format fallbacks. Keep the variant selection logic simple so caching remains effective.
Sample asset pipeline tasks
- Source fonts are checked into a design asset repository or ingested into the build system.
- CI runs pyftsubset for each target language or route and produces WOFF2 files with stable names derived from a hash of the subset.
- The CI uploads files to the CDN and publishes a manifest JSON that lists available subsets and their coverage.
Final practical checklist before deployment
- Confirm essential glyphs and layout features render correctly across target browsers.
- Compare bytes and time to paint between full family and subset builds.
- Preload the single most critical font resource and use font display values that match your UX goals.
- Ensure CDN caching and consistent filenames so clients benefit from long lived caches.
Applying WOFF2, variable fonts, and thoughtful subsetting reduces page weight and client CPU work while preserving typography. The recommended path is to start with conservative language level subsets, automate them in your build pipeline, test widely, and iterate based on real measurements from your audience.