How to Optimize Web Fonts for Sub-100ms LCP
Web Font Delivery and Layout Stability
Typography is critical for creating an engaging digital identity, but poorly optimized custom web fonts are a primary cause of high Largest Contentful Paint (LCP) and Cumulative Layout Shift (CLS) scores. When a browser downloads an HTML document, it discovers text elements that use custom fonts.
If the font files are not cached locally, the browser has to make a choice. It can either hide the text until the font file arrives, resulting in a Flash of Invisible Text (FOIT), or display a system font and swap it once the custom font loads, resulting in a Flash of Unstyled Text (FOUT).
Both scenarios degrade user experience; FOIT frustrates users by hiding information, while FOUT causes layout shifts that disrupt reading. Achieving sub-100ms LCP requires optimizing font delivery at every step of the rendering lifecycle.
The history of digital font formats explains the evolution of web typography optimization. In the early web, developers were limited to system-safe fonts like Arial, Times New Roman, and Georgia.
With the introduction of the @font-face rule, custom typography became possible. Initial formats included Embedded OpenType (EOT) for Internet Explorer, TrueType (TTF), and OpenType (OTF).
While TTF and OTF support extensive vector glyph structures, their file sizes were often huge, running into hundreds of kilobytes. The Web Open Font Format (WOFF) introduced metadata packaging and basic compression.
WOFF2 improved this further by applying the Brotli compression algorithm, yielding file sizes 30% smaller than WOFF. WOFF2 is now the standard for modern web performance.
Font Subsetting and Compression Techniques
However, simply converting a TTF or OTF font to WOFF2 is not enough. A standard font file contains thousands of glyphs supporting multiple languages, math symbols, and special characters.
For a website targeting a specific language, like English, the vast majority of these glyphs are never used. Subsetting allows developers to strip unused characters, generating a language-specific font file.
A subsetted Latin-only WOFF2 file is often under 15KB, whereas the unoptimized font can exceed 200KB. You can subset fonts using command-line tools like "pyftsubset" from Fonttools:
pyftsubset custom-font.ttf --unicodes="U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+2000-206F,U+2074,U+20AC,U+2122,U+2191,U+2193,U+25A0-25FF,U+FEFF,U+FFFD"
This command outputs a WOFF2 file containing only the characters needed for standard Western European languages. Reducing the payload size is the most direct way to accelerate browser rendering pipelines and lower network overhead.
Configuring WOFF2 Font Loading
Once the font files are subsetted, they must be loaded efficiently. By default, browsers only request font files after parsing the DOM and CSSOM and matching styles to visible elements.
This delayed request contributes to slow LCP times. To bypass this, developers can use the link element to preload critical fonts in the HTML header:
<link rel="preload" href="/fonts/inter-subset.woff2" as="font" type="font/woff2" crossorigin>
Crucially, using "font-display: swap" in the "@font-face" declaration ensures the browser displays a system fallback font immediately, preventing FOIT:
@font-face {
font-family: 'Inter';
src: url('/fonts/inter-subset.woff2') format('woff2');
font-weight: 400;
font-style: normal;
font-display: swap;
}
Managing Swapping and Font Display Behaviors
The font-display CSS descriptor controls how a font is rendered depending on whether it has loaded. The options include:
block: The browser hides the text for up to 3 seconds while loading the font, showing a blank space.swap: The browser immediately renders fallback text, then swaps in the custom font once loaded.fallback: Hides text for a short time (100ms), then uses fallback if the font is unavailable.optional: The browser only uses the custom font if it is already cached, avoiding swaps entirely.
swap provides the fastest time-to-content, while optional offers the best stability against layout shifts.
Preventing Layout Shifts using Size Adjust Overrides
While "font-display: swap" prevents invisible text, it can still cause layout shifts if the fallback font has different dimensions than the custom font. To prevent this, developers can use CSS overrides on the fallback font.
By adjusting properties like "size-adjust", "ascent-override", "descent-override", and "line-gap-override" inside a custom "@font-face" definition, you can stretch or compress the fallback font (like Arial or Times New Roman) to match the custom font. To calculate these percentages, designers match the width metrics of capital 'x' and baseline alignments between the fonts. This ensures that when the custom font swaps in, the text takes up the exact same space, reducing Cumulative Layout Shift (CLS) to zero:
@font-face {
font-family: 'Fallback-Arial';
src: local('Arial');
ascent-override: 90%;
descent-override: 22%;
line-gap-override: 0%;
size-adjust: 97%;
}
body {
font-family: 'Inter', 'Fallback-Arial', sans-serif;
}
- ascent-override: Modifies the font's ascending height parameter to align fallback layouts.
- descent-override: Modifies the descending metric to match native display lines.
- size-adjust: Scales system text grids to normalize visual shifts during swapping.
Automated Font Optimization in Modern Frameworks
Modern web frameworks like Next.js automate these tasks through dedicated libraries. The "next/font" module hosts fonts locally at build time, generates CSS size-adjust overrides automatically, and preloads fonts without layout shifts or manual setup. This automatic optimization ensures developers can focus on aesthetic design choices without introducing technical performance regressions, making premium web typography easy to achieve.
Web Performance and Font Optimization with Bramsley
Core Web Vitals Perspective: Font optimization is critical to achieving sub-100ms LCP scores. Bramsley Digital Studio designs automated font-subsetting workflows and preloading mechanisms at the edge. By eliminating layout shifts and asset bottlenecks, we ensure search-engine friendly, instant load speeds globally.
Partner with us to optimize your site's performance metrics. Work with our web performance team.