perf(desktop): Settings loads as a chunk of its own the first time it opens, making room under the renderer's bundle budget

Merged
DA
4d ago
+50-10

Main's renderer/renderer.js has reached its bundle-budget ceiling, 795,845 gzipped bytes (baseline 757,948 plus 5%). Every desktop PR that adds a few hundred bytes now fails pnpm check:affected's desktop build. #2730 is 606 bytes over and #2733 is 116 over, and each is a small feature.

AGENTS.md says the baseline moves only for a deliberate library adoption, never for drift, so this PR makes room instead of moving it. Settings becomes a chunk of its own, loaded the first time it opens (React.lazy over a dynamic import() of desktop-settings.tsx, under a Suspense with no fallback):

  • About 4.1 KB gzipped (desktop-settings-*.js) leaves the up-front bundle. That is what's left once the Settings modules other surfaces share (the palette's page names, the confirm dialog, the menu rows) stay behind.
  • build.mjs already leaves a chunk reached only by a dynamic import() out of the measurement, and the renderer has shipped as ES modules with chunks since #2506. So the build needs no change. The precedents are #2273 (session recorder) and #2581 (xterm), done the same way through their own entries.
  • The chunk is a local file, so Settings stands a frame later, over nothing in the meantime.
  • bundle-budget.json is unchanged.

sidebar-collapse.test.ts's one test that opens Settings through the shell now waits for the chunk, by importing it inside act. No real clock.

Evidence

The desktop build passes its budget. CI builds nothing for the Mac, so it could not verify that Settings opens in the packaged app. Only the Linux build and the jsdom tests ran here, not a Mac verify.sh run.

šŸ¤– Generated with Claude Code


Devin Review


Summary by cubic

Splits Settings into its own lazy-loaded chunk so the desktop renderer bundle fits its size budget again, unblocking small feature PRs that were failing the desktop build. Settings now loads the first time it opens instead of with every window, and Escape pressed while the chunk loads leaves Settings just as it would once drawn, not the plan behind it. No build or budget config changes; the test that opens Settings now waits for the chunk.