Skip to content
Docs

Command palette

Jump to a page or view, or find a todo by name.

Changelog

Public pages paint before any JavaScript arrives

On a slow phone connection the landing, login and docs paint in about half a second instead of two to two and a half: the CSS of a first visit is inline, the scripts load after it, and every page starts from three script files instead of 33.

Markdown

A first visit to a public page no longer waits for JavaScript to paint. On the measurement profile (Slow 4G, 4x CPU slowdown, empty cache, the built Worker) the landing paints after about 0.7 s instead of 2.6 s, /login and /docs after about 0.5 s instead of 2 to 2.3 s, and hydration stays where it was or comes earlier. The method and every number are in docs/measurements/2026-11-05-first-paint.md; the rule that keeps it this way is W15 in Web conventions.

  • Three startup files. The modules every page loads before it hydrates are now the entry with the app's own code, one vendor chunk and Rolldown's runtime, instead of 33 files. Route chunks keep automatic splitting, so a page loads the modules it loaded before. (be64a8c)
  • Inline CSS on a first visit. The root stylesheet is a side-effect import, so Start can inline it. A request without a session gets one <style> in its HTML; a signed-in request keeps the stylesheet link its cache already holds. (fc5e387)
  • Scripts after the stylesheet. The head carries no modulepreload; a small inline script at the end of the body adds the route chunks' preloads once the stylesheets have loaded, as x.com does. (a6913a7)
  • Early Hints. A page without a session names its font and any stylesheet it did not inline (never a script) in a Link header. Cloudflare turns it into a 103 Early Hints answer once the zone has Early Hints on (Speed, Settings, Content Optimization); without the toggle nothing changes. (11f1e2a)
  • The sign-in figure waits. The engine drawing on the sign-in pages (300 KB compressed) is requested once the form is interactive, so it no longer delays the form on a slow connection. (3d77751)

scripts/measure-first-paint.mjs measures first paint and hydration of any deployed URL on the same profile; it takes Playwright from PLAYWRIGHT_CORE instead of adding a dependency.

Edit on GitHubDocumentation is in English.