perf(fonts): serve Geist from the site instead of Google Fonts - #20
Merged
Merged
Conversation
Every page loaded a stylesheet from fonts.googleapis.com in <head>, and a stylesheet blocks the first paint until it arrives. Where Google cannot be reached, as in mainland China without a proxy, the request hangs until it times out, about 30 seconds, and the page shows nothing until then. - Geist 400/500/600/700 and Geist Mono 400/500 come from the Fontsource packages already in devDependencies (the same files as Google Fonts: version, advance widths, outlines and kerning match). Vite bundles them under hashed names with the subsets split by unicode-range, so a page downloads only the Latin files, and each face uses font-display: swap. - The Latin files of Geist 400, 500 and 600 and Geist Mono 400 are preloaded from every page. - Font files are never inlined into the stylesheet as base64: Vite would otherwise inline the subsets under 4 KB and every page would download them before its first paint. - Until Geist has loaded, text is set in Arial (Liberation Sans or Arimo on Linux) and Courier New, scaled with size-adjust and the ascent, descent and line-gap overrides so that the swap does not reflow the page. The figures come from the English text of the site's pages. - Chinese text uses the system's font (PingFang SC, Microsoft YaHei, Noto Sans CJK SC) instead of downloading Noto Sans SC. - The preconnects to fonts.googleapis.com and fonts.gstatic.com are gone. The Open Graph images still read their outlines from the same packages and come out byte-identical. Co-Authored-By: Claude Opus 5.5 <[email protected]>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Every page loaded a stylesheet from
fonts.googleapis.comin<head>. A stylesheet blocks the first paint until it arrives, so where Google cannot be reached (mainland China without a proxy) the request hangs until it times out, about 30 seconds, and the page stays blank until then. The preview browser used for this change cannot reach Google either: on the currentmainbuild, the request ran 30.0 s, failed, and no font loaded.What changes
@fontsource/geistand@fontsource/geist-mono, already indevDependencies(5.3.0). They are the same files Google Fonts serves: Geist 1.800 and Geist Mono 1.701, with identical advance widths, outlines and kerning (compared with fontkit). Vite bundles them under hashed names, each weight split into subsets byunicode-rangeas on Google Fonts, so a page downloads only the Latin files; every face usesfont-display: swap. New component:src/components/Fonts.astro, included byBase.astro.crossoriginso the preload is reused.vite.build.assetsInlineLimitnow keeps.woff/.woff2as files and leaves everything else at the default, so Astro's stylesheet and script inlining is unchanged.size-adjust,ascent-override,descent-overrideandline-gap-overrideso the swap does not reflow the page. Liberation Sans/Arimo and Liberation Mono/Cousine share those metrics, so the same figures apply on Linux.size-adjustis the width ratio over the English text of the site's 22 English pages, per weight.fonts.googleapis.comandfonts.gstatic.comare removed.Checks
pnpm build(pnpm 10) passes;tsc --noEmitpasses. No page indist/referencesfonts.googleapis.comorfonts.gstatic.com.Geist Fallbackis 1.0000 of Geist's width at 400, 500, 600 and 700, line boxes are equal (20.5 px at 16 px), and 149 of 150 long paragraphs wrap to the same number of lines in a 640 px column. Unadjusted Arial is 2.2% narrower at 400 and 4.5% at 500.@font-facerules; it contains nodata:fontURL.src/lib/og.tsreads its outlines from the same packages) are byte-identical tomain's.main.🤖 Generated with Claude Code