Font Converter
Core Web Vitals

Font Loading Still Causes 23% of LCP Failures — 2026 Optimization Checklist

HTTP Archive data shows fonts are the #2 cause of poor LCP scores after images. This updated checklist covers every optimization in the stack — WOFF2 format, subsetting, font-display, preloading, and CSS metric overrides — with direct links to the tools that handle each step.

TL;DR

Data source: Chrome UX Report (CrUX) & HTTP Archive, January 2026

  • Fonts are involved in 23% of pages failing LCP thresholds, making them the #2 cause after images
  • The complete font optimization stack: WOFF2 format + subsetting + font-display:swap + preload
  • CSS metric overrides (size-adjust, ascent-override) eliminate font-swap CLS without JavaScript
  • Each optimization step maps to a specific tool — no manual font engineering required

Share this page to:

Fonts and LCP: The 2026 Data

HTTP Archive's latest crawl data establishes fonts as the second most common cause of Largest Contentful Paint failures across the web. Of all pages that fail LCP thresholds, 23% have fonts on the critical path contributing to that failure — a problem that has persisted despite years of tooling improvements.

The root cause is structural: fonts live on the critical rendering path. The browser must parse HTML, discover the CSS, parse the CSS, find the @font-face declarations, request the font files, download them, and only then render text. That chain — HTML → CSS → font request → render — means any delay at any stage pushes LCP further out.

LCP Failure CausePercentage of Failures
Images34%
Fonts23%
JavaScript19%
Server response time15%
CSS9%

Three mechanisms by which fonts fail LCP

1

Render-blocking font requests

@font-face without font-display causes the browser to block text rendering until the font file is fully downloaded. The browser discovers the font only after parsing CSS, adding a full round-trip of latency before any text renders.

2

Large unsubsetted font files

A full Latin font can be 200–300KB. On a 4G connection that's 400–600ms of download time. On mobile networks it can exceed 1.5s. Subsetting to the characters you actually use drops this to 20–70KB.

3

font-display:block (FOIT)

The browser default in many implementations: hide text for up to 3 seconds while the font loads. This means the LCP element — often a heading or hero text — is invisible until the font arrives, directly delaying LCP.

Why this persists in 2026

Font optimization requires coordinating four separate concerns (format, size, display behavior, loading priority) that touch CSS, HTML, and the build pipeline. Most sites solve one or two, not all four. This checklist addresses the complete stack.

font-display Strategies Compared

The font-display descriptor controls what browsers do while waiting for a font to load. Choosing the wrong value is one of the most common sources of both LCP failures and unexpected FOIT.

ValueBehaviorBest For
autoBrowser default — usually block behaviorNot recommended
blockInvisible text (FOIT) for up to 3 secondsNever use for body/headings
swapFallback font immediately, swaps when loadedBody text, most headings
fallback100ms block, then fallback, ~3s swap windowBrand headings where swap is undesirable
optional100ms block, may never swap based on connectionCritical LCP text, hero sections

/* Recommended @font-face for body text */

@font-face {
  font-family: 'Inter';
  src: url('/fonts/inter-var.woff2') format('woff2');
  font-weight: 100 900;
  font-style: normal;
  font-display: swap;
}

Why optional beats swap for LCP-critical text

For hero headings that are your LCP element, font-display: optional is superior. It prevents any font swap from occurring after the initial 100ms window — meaning if the font isn't cached, the browser sticks with the fallback and avoids triggering a late LCP recalculation due to a swap event. The font is still downloaded and cached for subsequent page views.

Font Preloading and Resource Priority

Preloading tells the browser about critical font files early — before HTML parsing discovers them via CSS. This moves font discovery from late in the waterfall to the very start of the request chain.

<!-- In <head>, before your stylesheet -->

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

<!-- For the single most critical font, add fetchpriority -->
<link
  rel="preload"
  href="/fonts/inter-regular.woff2"
  as="font"
  type="font/woff2"
  crossorigin
  fetchpriority="high"
>

Preload rules

  • +Preload 1–2 critical fonts only (body regular weight)
  • +Always include crossorigin — even for same-origin fonts
  • +Only preload WOFF2 (no TTF or WOFF preloads)
  • +Place preload tags before stylesheets in <head>

Over-preloading risks

  • -Preloading 3+ fonts competes with LCP images for bandwidth
  • -Unused preloads generate console warnings and waste bytes
  • -Never preload fonts served via Google Fonts CDN
  • -Omitting crossorigin causes a double-fetch

fetchpriority="high" for the single most critical font

Adding fetchpriority="high" to your primary body font preload signals to the browser that this resource is more important than other preloads. Use it for one font only — the regular-weight body font used above the fold. This is distinct from a standard preload and instructs the browser to deprioritize competing requests.

Eliminating Font-Related CLS

When a fallback font swaps to a web font, the two fonts almost never have identical metrics — different x-height, ascent, descent, and character width values cause text to reflow, pushing other elements around the page. This is a primary source of Cumulative Layout Shift.

CSS font metric overrides let you adjust the fallback font's metrics so that it occupies exactly the same space as the web font, making the swap visually imperceptible.

/* Web font + metric-matched fallback */

/* Primary web font */
@font-face {
  font-family: 'Inter';
  src: url('/fonts/inter-var.woff2') format('woff2');
  font-weight: 100 900;
  font-display: swap;
}

/* Metric-matched fallback — eliminates CLS */
@font-face {
  font-family: 'Inter-Fallback';
  src: local('Arial');
  size-adjust: 107%;
  ascent-override: 90%;
  descent-override: 22%;
  line-gap-override: 0%;
}

body {
  font-family: 'Inter', 'Inter-Fallback', Arial, sans-serif;
}
CSS PropertyWhat It ControlsTypical Range
size-adjustOverall glyph scaling to match character widths95%–115%
ascent-overrideHeight above baseline (affects line-height)85%–100%
descent-overrideDepth below baseline (affects line-height)15%–30%
line-gap-overrideExtra spacing between lines0%–10%

Before: Without overrides

Typical CLS score0.15

Fails Google's “Good” threshold of 0.1

After: With overrides

Typical CLS score0.02

Passes “Good” threshold with significant margin

Automated alternatives

Next.js next/font calculates and applies these overrides automatically for Google Fonts. The open-source Fontaine library does the same for any build pipeline. Both generate the correct override values by reading the font file's internal metrics tables.

The Complete 2026 Optimization Checklist

Every item in this checklist addresses a specific, measurable failure mode. Implement all seven to achieve the full LCP and CLS improvement.

1.Use WOFF2 format for all fonts

WOFF2 uses Brotli compression, achieving 20–30% better compression than WOFF and 50–70% better than TTF/OTF. In 2026, every target browser supports WOFF2 — serve nothing else.

2.Subset to needed character ranges

A full Latin font contains 600+ glyphs. English content needs ~100. Removing unused glyphs, plus associated kerning data, reduces file size by 60–75% with no visible quality difference.

3.Set font-display: swap (or optional for hero text)

Eliminates FOIT by showing a fallback font immediately. Use swap for body text. For LCP-critical hero headings, consider optional to prevent late font-swap events from delaying LCP recalculation.

4.Preload the primary body font

Add a <link rel="preload"> for your main body font WOFF2 file. Include crossorigin. Add fetchpriority="high" to the single most critical font. Limit to 1–2 preloads total.

5.Use CSS metric overrides for fallback fonts

Apply size-adjust, ascent-override, descent-override, and line-gap-override to match fallback font metrics. Eliminates font-swap CLS without any JavaScript.

6.Self-host when possible

Third-party font CDNs (even Google Fonts) add a DNS lookup, TCP connection, and TLS handshake before the first byte of the font file. Self-hosting eliminates this cross-origin latency — typically saving 150–400ms.

7.Limit total font files to 3–4 maximum

Each font file is a separate network request. Most sites can cover all typographic needs with 3–4 files: body regular, body bold, heading variable. Audit your font-face declarations and remove unused weights.

What to Do Now

Each step in the optimization checklist maps directly to a tool that handles the implementation without requiring manual font engineering. Start with the format and size optimizations (steps 1–2), then address loading behavior (steps 3–4), then CLS elimination (step 5).

CSS Generator

Checklist steps 3 + 5

Generate optimized @font-face CSS with font-display included and metric-matched fallback @font-face rules. No manual metric calculation required.

Open CSS Generator

Font Subsetter

Checklist step 2

Upload a font and select a character range. Outputs a trimmed font file 60–75% smaller than the original, ready to drop into your font stack.

Open Font Subsetter

Webfont Generator

Checklist step 1

Convert any font to WOFF2 and produce a complete web-ready font package with the correct @font-face declarations pre-written.

Open Webfont Generator

Base64 Encoder

Critical path inlining

Inline tiny critical fonts (icon fonts, subsetted display fonts) directly into CSS as Base64 data URIs to eliminate the font network request entirely.

Open Base64 Encoder

Related Resources

Sarah Mitchell

Written & Verified by

Sarah Mitchell

Product Designer, Font Specialist

Optimize Your Font Loading

Run through the full checklist with our tools. Generate optimized CSS, subset your fonts, and convert to WOFF2 — all without installing anything.

Core Web Vitals Font Loading FAQs

Common questions about fonts and LCP, CLS, and performance optimization