Skip to content

perf: preload Poppins + font-display: swap (metric: CLS) - #4

Open
phyceClaw wants to merge 1 commit into
phyce:mainfrom
phyceClaw:perf-font-preload-cls
Open

perf: preload Poppins + font-display: swap (metric: CLS)#4
phyceClaw wants to merge 1 commit into
phyce:mainfrom
phyceClaw:perf-font-preload-cls

Conversation

@phyceClaw

Copy link
Copy Markdown

Metric targeted: Cumulative Layout Shift

Homepage mobile CLS is currently 0.330 (Lighthouse, Chrome 151, mobile preset). Lighthouse attributes the shift to font loading — not to the plugin table:

layout-shift score 0.3299
  culprit: Media element lacking an explicit size
  culprit: Web font loaded — /fonts/poppins-400.woff2
  culprit: Web font loaded — /fonts/poppins-500.woff2

Cause

The three @font-face blocks in resources/css/app.css declare no font-display, so the browser applies the default auto (block, then swap). There was also no <link rel=preload>, so the fonts were only discovered once app.css had been parsed. Text paints in the fallback and then reflows when Poppins arrives.

Change

  • font-display: swap on all three faces.
  • Preload the two weights that render above the fold (400 and 500) in app.blade.php.

Both font files are ~7.8 KB, so the preload cost is negligible relative to the shift it removes. Weight 700 is deliberately not preloaded — it is not an above-the-fold face and was not flagged as a shift culprit.

Verification

npm run build passes and font-display:swap is present in the emitted app-*.css.

⚠️ The CLS improvement itself is projected, not measured — this VPS does not run the app (build-only), so I could not re-run Lighthouse against the change. Worth re-running PSI on the deploy preview to confirm.

🤖 Generated with Claude Code

Metric: Cumulative Layout Shift (mobile home 0.330 -> expected ~0)

Lighthouse attributes the homepage layout shift to font loading, not to
the plugin table:

  layout-shift score 0.3299
    culprit: Web font loaded - /fonts/poppins-400.woff2
    culprit: Web font loaded - /fonts/poppins-500.woff2

The @font-face blocks had no font-display, so the browser used the
default `auto` (block, then swap) and there was no preload, so the fonts
were only discovered after app.css parsed. Text painted in the fallback
and then reflowed once Poppins arrived.

Adds font-display: swap to all three faces and preloads the two weights
that render above the fold (400 and 500). Both files are ~7.8 KB, so the
preload cost is negligible against the shift it removes. Weight 700 is
not preloaded - it is not an above-the-fold face and Lighthouse did not
flag it as a shift culprit.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant