Skip to content

perf: wave D — self-host Inter latin subset, preload, font-display: optional#47

Merged
Bissbert merged 1 commit into
mainfrom
feature/perf-wave-d
May 18, 2026
Merged

perf: wave D — self-host Inter latin subset, preload, font-display: optional#47
Bissbert merged 1 commit into
mainfrom
feature/perf-wave-d

Conversation

@Bissbert
Copy link
Copy Markdown
Contributor

Summary

Replaces the @fontsource-variable/inter CSS @import with a self-declared @font-face block targeting a single 48 KiB latin subset shipped from /public/fonts/inter-latin-variable.woff2, plus a <link rel="preload"> in BaseLayout.astro so the font byte stream races CSS parsing.

Changes

  • src/styles/global.css — removed the Inter @fontsource-variable @import (which shipped 7 @font-face blocks: cyrillic, cyrillic-ext, greek, greek-ext, vietnamese, latin-ext, latin); replaced with a single @font-face block for the latin subset with font-display: optional.
  • src/layouts/BaseLayout.astro — added <link rel="preload" as="font" type="font/woff2" crossorigin="anonymous" href="/fonts/inter-latin-variable.woff2"> to <head>.
  • public/fonts/inter-latin-variable.woff2 — new file (48 KiB), copied from the fontsource latin subset.

Why

  • Critical CSS shrinks: removed 6 unused @font-face declarations for character ranges the English-only site never renders.
  • No FOUT / CLS contribution: font-display: optional means if the font isn't ready within ~100 ms the system font is used and Inter swaps in only on subsequent navigations (cached by then). The preload tag means the latin subset typically arrives before first paint anyway.
  • Cache already configured: wave A's _headers rule covers /fonts/* with Cache-Control: public, max-age=31536000, immutable, so repeat visits skip the network round-trip entirely.

JetBrains Mono kept on @fontsource — only used in below-fold code blocks, not critical path.

WD2 (scope .monaco-editor / .skeleton / .prose overrides) deliberately skipped — .prose is used by ~10 routes (every learn/tools/quiz page), so a separate import wouldn't materially reduce unused CSS; the .monaco-editor and .skeleton rules are <20 lines combined. Marginal benefit, not worth the refactor.

Test plan

  • npm run build — 916 pages built in 9.04s, no errors
  • Curl-verify /fonts/inter-latin-variable.woff2 returns 200 with the immutable cache header after deploy
  • Re-run Lighthouse on the 5 baseline URLs; confirm "Reduce unused CSS" diagnostic improves and font-load CLS contribution is zero

…ptional

Replaces the @fontsource-variable/inter @import with a self-declared
@font-face block targeting a single 48 KiB latin subset shipped from
/public/fonts/inter-latin-variable.woff2, plus a <link rel="preload">
in BaseLayout.astro so the font byte stream races CSS parsing.

- Removes 6 unused @font-face blocks (cyrillic, cyrillic-ext, greek,
  greek-ext, vietnamese, latin-ext) that fontsource ships by default —
  the site is English-only.
- font-display: optional eliminates FOUT/FOIT entirely; with the
  preload tag the latin subset typically arrives before first paint.
- Cache rule already in place from wave A (/fonts/* immutable,
  max-age=31536000), so repeat visits skip the network round-trip.

JetBrains Mono kept on @fontsource for now — only used in below-fold
code blocks, not critical path.

Part of audits/perf-2026-05/ remediation. Lighthouse re-run pending.
@cloudflare-workers-and-pages
Copy link
Copy Markdown

cloudflare-workers-and-pages Bot commented May 18, 2026

Deploying gemmology-dev with  Cloudflare Pages  Cloudflare Pages

Latest commit: da4fb92
Status:🚫  Build failed.

View logs

@github-actions
Copy link
Copy Markdown

🚀 Preview deployed to: https://c1729110.gemmology-dev.pages.dev

@Bissbert Bissbert merged commit ce3f69b into main May 18, 2026
5 of 6 checks passed
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