Web Font Loading Strategy
debt(d5/e3/b3/t7)
Closest to 'specialist tool catches it' (d5). The detection_hints list Lighthouse, PageSpeed Insights, and webfont-loader — these are specialist performance auditing tools, not default linters or compilers. The code_pattern confirms the issues are visible via audit runs rather than during authoring or with default tooling.
Closest to 'simple parameterised fix' (e3). The quick_fix describes adding font-display: swap to @font-face rules, preloading critical font files, and self-hosting fonts instead of Google Fonts. These are a small set of targeted changes within one concern area (CSS + HTML head), slightly more than a one-liner but contained within one component. No cross-file refactor required.
Closest to 'localised tax' (b3). The applies_to context is web broadly, but font loading strategy primarily impacts the CSS/HTML head and asset pipeline of one project. While it affects render performance globally, it doesn't impose a strong gravitational pull on every future code change — it's a set of configuration decisions that, once corrected, stays corrected unless new fonts are added.
Closest to 'serious trap' (t7). The misconception field states that font-display: swap is commonly believed to always improve UX, but it actually causes FOUT and potentially significant CLS when fallback and web font metrics differ. This directly contradicts the intuitive expectation that 'swap = better', and the correct answer (font-display: optional for secondary fonts, fallback metric adjustment) is non-obvious and contradicts how similar simple CSS properties behave elsewhere.
Also Known As
TL;DR
Explanation
Font loading problems: FOIT (Flash of Invisible Text) — browser hides text while font downloads; FOUT (Flash of Unstyled Text) — fallback font shown then swaps; CLS (Cumulative Layout Shift) — font metric difference causes layout reflow. Solutions: font-display: swap (show fallback immediately, swap when loaded — eliminates FOIT but allows FOUT), font-display: optional (use font only if already cached), preloading critical fonts (<link rel=preload as=font>), font subsetting (only include used characters), self-hosting (avoids external DNS lookup), and size-adjust + ascent-override to match fallback font metrics (eliminates CLS).
Common Misconception
Why It Matters
Common Mistakes
- Not preloading critical fonts — they are discovered late in the render pipeline.
- Loading all weights and variants — load only the weights/styles actually used.
- Google Fonts without self-hosting — extra DNS lookup + connection adds 100-400ms latency.
- No fallback font metrics adjustment — causes layout shift when web font loads.
Code Examples
/* Loading fonts without display strategy — FOIT:
@font-face {
font-family: 'MyFont';
src: url('font.woff2');
/* No font-display — browser hides text for 3 seconds */
}
/* Slow connection: 3-second invisible text */
/* Optimised font loading: */
@font-face {
font-family: 'MyFont';
src: url('font.woff2') format('woff2');
font-display: swap; /* Show fallback immediately */
unicode-range: U+0000-00FF; /* Subset: Latin only */
}
/* Match fallback metrics to minimise CLS: */
@font-face {
font-family: 'MyFont-fallback';
src: local('Arial');
size-adjust: 104%; /* Match web font's cap height */
ascent-override: 95%;
}
body { font-family: 'MyFont', 'MyFont-fallback', sans-serif; }
<!-- Preload critical font: -->
<link rel="preload" href="/fonts/myfont.woff2" as="font" type="font/woff2" crossorigin>