How this site scores Lighthouse 100 on mobile
A static Astro build, zero client framework, and a strict CSP — the three decisions that keep all four Lighthouse categories pinned at 100.
The release gate for this site is blunt: Lighthouse 100 / 100 / 100 / 100 on mobile, run against production. Here is what actually keeps it there.
Ship almost no JavaScript
The fastest script is the one you never send. This whole site ships two tiny inline boot scripts and two small same-origin modules — the theme toggle and the language switcher. Everything else is static HTML and one hand-written stylesheet. There is no client framework to hydrate, so Total Blocking Time stays at zero.
Make the strict CSP a build-time invariant
Best Practices drops the moment the console logs a Content-Security-Policy violation. Rather than hope, the build fails if any inline script isn’t covered by a hash:
// astro.config.mjs
security: {
csp: {
algorithm: "SHA-256",
scriptDirective: { hashes: SCRIPT_HASHES },
},
}
A postbuild step re-hashes every inline script in dist/ and asserts the
hash is present in that page’s CSP <meta>. Drift becomes a red build, not a
silent regression in the field.
Reserve space for everything
Cumulative Layout Shift is mostly about fonts and images. Fonts load with
font-display: optional and unicode-range-scoped subsets, so a glyph swap
never reflows the page. Images carry explicit dimensions. The hero — the LCP
element — is never animated.
None of this is exotic. It is the same handful of decisions applied consistently, and verified on every build instead of trusted.