perf: bundle React in production mode
`build:js` was shipping React's development build. That cost 222 KB of the 566 KB bundle (61 KB of 164 KB gzipped), ran every element creation through dev-only validation, and left `StrictMode` double-invoking effects — so `fetchFeed` fired twice and every reader downloaded the feed twice on every single load. On a 4G/4×-CPU profile with the cache cold: first contentful paint 1480ms → 972ms, the feed on screen 1766ms → 1261ms, and two feed requests → one. The flag is `--production` and not `--define process.env.NODE_ENV='"production"'`, which is the obvious-looking version and produces a bundle that does not run at all: the define flips React to its production build while the JSX transform keeps emitting `jsxDEV`, so the page dies on `z is not a function` with a blank body. Both variants build clean, typecheck clean and pass all 843 tests, because nothing in the suite executes the bundle — so AGENTS.md now says to open a browser before believing this one. Co-Authored-By: Claude Opus 5 (1M context) <[email protected]>
This commit is contained in:
co-authored by
Claude Opus 5
parent
23ad2ad797
commit
a7cf59d8e4
@@ -101,6 +101,23 @@ bun test --test-name-pattern "year-less"
|
||||
BASE_PATH=/gacha-event-tracker/ bun run build
|
||||
```
|
||||
|
||||
**`build:js` passes `--production`, and that flag is load-bearing.** Without it Bun bundles React's
|
||||
*development* build: 566 KB rather than 344 KB (164 KB vs 103 KB gzipped), every element creation
|
||||
validated at runtime, and `StrictMode` double-invoking effects — which in this app means
|
||||
`fetchFeed` runs twice and every reader downloads the feed twice on every load. It shipped that way
|
||||
until 2026-08-20; on a 4G/4×-CPU profile fixing it moved first contentful paint from 1480 ms to
|
||||
972 ms.
|
||||
|
||||
**Do not reach for `--define process.env.NODE_ENV='"production"'` instead.** It looks equivalent and
|
||||
produces a bundle that does not run. The define flips React to its production build while the JSX
|
||||
transform still emits `jsxDEV` calls into `react/jsx-dev-runtime`, so the page dies on
|
||||
`jsxDEV is not a function` — minified to `z is not a function`, which is what it looks like in a
|
||||
built copy. `--production` switches the transform *and* the env together, which is why it is the
|
||||
only one of the two that works. Setting `NODE_ENV=production` in the environment has the same defect
|
||||
as the define. **A change here must be loaded in a browser, not merely built** — both broken variants
|
||||
build clean, typecheck clean and pass all 843 tests, because nothing in the suite executes the
|
||||
bundle.
|
||||
|
||||
**Tests must never need build output.** They run before `bun run build` in CI; anything reading
|
||||
`public/` must create its own fixture tree instead.
|
||||
|
||||
|
||||
Reference in New Issue
Block a user