← Home ← Codex ← DEBT
Browse by Category
+ added · updated 7d
← Back to glossary

Web Font Loading Strategy

Frontend CSS3 Intermediate
debt(d5/e3/b3/t7)
d5 Detectability Operational debt — how invisible misuse is to your safety net

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.

e3 Effort Remediation debt — work required to fix once spotted

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.

b3 Burden Structural debt — long-term weight of choosing wrong

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.

t7 Trap Cognitive debt — how counter-intuitive correct behaviour is

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.

About DEBT scoring →

Also Known As

FOIT FOUT font-display font loading web fonts

TL;DR

Controlling how custom fonts load to avoid FOIT (invisible text), FOUT (flash of unstyled text), and layout shift — using font-display, preloading, and system font stacks.

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

font-display: swap always improves user experience — swap eliminates FOIT but causes FOUT and potentially significant CLS if fallback and web font have very different metrics; font-display: optional may give better UX for secondary fonts.

Why It Matters

FOIT causes text to be invisible for 1-3 seconds on slow connections — font-display: swap shows text immediately while the web font loads in the background.

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

✗ Vulnerable
/* 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 */
✓ Fixed
/* 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>

Added 16 Mar 2026
Edited 22 Mar 2026
Views 76
Rate this term
No ratings yet
🤖 AI Guestbook educational data only
| |
Last 30 days
0 pings T 0 pings W 0 pings T 0 pings F 0 pings S 0 pings S 1 ping M 0 pings T 1 ping W 3 pings T 1 ping F 0 pings S 3 pings S 1 ping M 0 pings T 0 pings W 0 pings T 0 pings F 0 pings S 0 pings S 0 pings M 0 pings T 0 pings W 0 pings T 0 pings F 0 pings S 1 ping S 1 ping M 1 ping T 0 pings W
No pings yet today
PetalBot 1
Amazonbot 18 Google 11 Perplexity 8 Scrapy 6 Ahrefs 5 SEMrush 5 ChatGPT 4 Unknown AI 2 Claude 2 Bing 2 Meta AI 1 Majestic 1 PetalBot 1
crawler 60 crawler_json 5 pre-tracking 1
DEV INTEL Tools & Severity
🟡 Medium ⚙ Fix effort: Low
⚡ Quick Fix
Add font-display: swap to @font-face rules; preload the most critical font file; self-host fonts instead of loading from Google Fonts to eliminate extra DNS lookup
📦 Applies To
css CSS3 web
🔗 Prerequisites
🔍 Detection Hints
Google Fonts @import in CSS blocking render; no font-display: swap; no preload on above-fold font; FOIT flash of invisible text
Auto-detectable: ✓ Yes lighthouse pagespeed-insights webfont-loader
⚠ Related Problems
🤖 AI Agent
Confidence: Medium False Positives: Low ✓ Auto-fixable Fix: Low Context: File


✓ schema.org compliant