Skip to content

perf(site): compile the engine from its sources and drop the directory facade chunk - #1450

Merged
apresmoi merged 2 commits into
mainfrom
untangle7/s6a-size
Oct 6, 2026
Merged

apresmoi merged 2 commits into
mainfrom
untangle7/s6a-size

Conversation

@apresmoi

@apresmoi apresmoi commented Oct 6, 2026

Copy link
Copy Markdown
Contributor

Change

Plan 7 step S6a, size tuning. Plan 7 itself cost almost nothing in client JS: its own modules add about +220 minified bytes across the S3 changes (each changed module minified on its own), and the +11% scene-router growth from #1350 was a move out of scene-datasets (both load on every page). The client JS growth since the plan 7 starting point (7c3bbfd79a, before #1350) is feature data, mostly the prepared dataset, moon-label and universe banks.

Two structural changes recover more than plan 7 cost:

  • The engine compiles from its sources in the client build, like the renderer and objects packages already do (site/build/package-sources.mts). The engine shipped as one tsup bundle, so the startup cover's single smoothstep import put the whole engine (29.6 KB raw) into every object page's first view. Its modules now split per module; the engine code the lazy chunks need moves into them.
  • The scene adapter imports the object directory statically. The router chunk that holds the adapter already imports the directory statically, so the dynamic import only produced a facade chunk.

With the duplicate chunk boundaries gone, the bundler also merges planetary-system-members into object-directory, object-entries into startup-world, and the core chunk into opacity-clock.

Size

Client JS from measure.mts; first view is the static closure of the page's scripts; total is first view plus every lazy chunk.

Measure Plan 7 start 7c3bbfd79a main b85b8784ef This PR vs main
Client JS raw 1,105,307 1,125,817 1,123,359 -0.22%
Client JS gzip 368,825 373,709 371,425 -0.61%
Client JS brotli 367,638 372,821 369,941 -0.77%
Client chunks 32 32 28 -4
/earth/, /itokawa/ first view raw 50,804 50,785 21,117 -58.4%
/earth/, /itokawa/ first view gzip 21,493 21,521 10,694 -50.3%
/earth/, /itokawa/ first-view chunks 12 12 10 -2
System routes first view gzip (/lmc/ and the 11 other system routes measured) 6,006 5,996 5,807 -3.2%
Worst route total gzip (object pages: /, /earth/, /dione/, /itokawa/) 326,638 331,505 329,221 -0.69%
Startup round trips, object / system routes 15 / 16-17 15 / 15-16 14 / 14-15 -1

Every route's first view, total and chunk count is at or below main and at or below the plan 7 start. Client JS total stays above the plan 7 start only by the feature data merged since.

What the per-leaf guard flags. L7 in strict mode lists failures that come from the merge itself, not from added work: the five lazy import targets (dynamic.*) carry +1.9% raw / +2.1% gzip because the engine code left the first view for them; merged chunks (startup-world, object-directory, opacity-clock, camera-layout) grow by what they absorbed; and object-directory now lists the Node-only prepared-world-context-node-source import that planetary-system-members used to list (an order finding; a real browser never takes that branch). No route total, first view, chunk count or round-trip count grows.

Evidence and limits

Proves the change: the local comparison lane (ci.mts --head <this branch> --base <main>), report mode:

  • Server answers (L2): 354/354 preview and 349/349 Cloudflare answers. Every difference is an HTML body's md5 at equal length, and the preview catalogue's entry-script size.
  • HTML: all 9,895 pages are byte-identical once _astro/<name>.<hash>.js references are normalized; no page added or removed.
  • Every other emitted file (35,000+ assets, data, CSS, both workers) is byte-identical; prerender and worker environments have 0 differences; only the client environment changes.
  • iPad slow-start gate on the same client bytes (ipad-slow-start.mts --target <preview> /earth/ /itokawa/, world summary held 1,200 ms): 4 of 4 cold loads reached data-ready.

Clean: pnpm typecheck, pnpm check:architecture (0 cycles), eslint on the changed files, site scene, directory, startup and build tests (112 pass).

Timing was not measured to the 2% band: the iPad gate checks that startup completes, not how fast.

PR rules

@apresmoi
apresmoi force-pushed the untangle7/s6a-size branch from c3fc5be to 3df0452 Compare October 6, 2026 17:56
@apresmoi
apresmoi merged commit d11c2c2 into main Oct 6, 2026
20 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