Blog: Hardening Font Loading for Page Speed — explicit display:swap
Hardening Font Loading for Page Speed: Explicit font-display: swap
Release: v1.0.383 · SEO-17 · seo_performance
Background
Core Web Vitals — and specifically the Cumulative Layout Shift (CLS) and First Contentful Paint (FCP) metrics — are directly influenced by how a browser handles web font loading. The font-display CSS descriptor controls this behaviour, and the swap value is the recommended choice for most body and UI text: it tells the browser to render text immediately using a system fallback font, then swap in the custom font once it has downloaded. This avoids invisible text during load (FOIT — Flash of Invisible Text) and keeps your page feeling fast.
What we found
During a routine SEO audit (ticket SEO-17) we reviewed src/app/layout.tsx, which is the root layout for the application and therefore the single point of truth for all font loading.
We use three fonts:
| Font | Role | Had explicit display: 'swap'? |
|---|---|---|
| JetBrains Mono | Code / monospace | ✅ Yes |
| Montserrat | Primary UI headings | ❌ No |
| Nunito | Primary UI body text | ❌ No |
Montserrat and Nunito are loaded via Next.js's built-in next/font/google module. Next.js does apply font-display: swap by default for all Google Fonts loaded this way — so there was no active bug. However, the explicit display property was absent from the configuration objects, meaning a future change to Next.js defaults, a CSS specificity conflict, or an inadvertent override could silently remove the swap behaviour without any obvious warning.
The fix
The resolution is straightforward: add display: 'swap' explicitly to both font configurations.
// src/app/layout.tsx
const montserrat = Montserrat({
variable: '--font-montserrat',
subsets: ['latin'],
display: 'swap', // ← added
});
const nunito = Nunito({
variable: '--font-nunito',
subsets: ['latin'],
display: 'swap', // ← added
});
const jetbrainsMono = JetBrains_Mono({
variable: '--font-jetbrains-mono',
subsets: ['latin'],
display: 'swap', // already present
});
This keeps all three font declarations consistent, makes the intended behaviour unambiguous to any future developer reading the file, and eliminates the CSS specificity risk entirely.
Why this matters for MTD compliance software
Our users are often mid-flow when completing quarterly submissions or reviewing transactions. A page that flickers, reflows, or delays text render during font load can break that flow and erode trust — especially on slower connections or lower-powered devices. Keeping Core Web Vitals healthy is not just an SEO concern; it is a direct quality-of-life improvement for landlords and self-employed taxpayers under time pressure to meet HMRC deadlines.
Impact summary
- User-visible change: None under current conditions.
- Risk mitigated: Future CSS specificity override silently disabling
font-display: swap. - Metrics affected: FCP and CLS stability (hardening, not improvement from current baseline).
- Files changed:
src/app/layout.tsxonly. - Breaking changes: None.