Symptom
The bundle-budget ratchet fails on development since cb7448bf ("remove the unfinished CleanStart Platform page"): /vulnerability-remediation grew from 317.8 KB to 345.3 KB gzipped (+27.5 KB, tolerance 5 KB). Absolute budgets are warn-only, so only the ratchet blocks.
Cause
Turbopack now emits the framer-motion runtime twice in production. Two chunks (0enzg3fle.a7y.js and 0bhimso_.o1iv.js in the current build) carry the same modules: every marker string (whileInView, onViewportEnter, whileHover, whileTap, layoutId, keyframes, spring, inertia, prefers-reduced-motion) appears with identical counts in both, and sampled content similarity is 0.97.
- One copy is in the global chunk loaded by all 616 routes (via
FadeUp in the layout tree).
- The second is in a chunk loaded by 46 marketing routes (the ones using
components/ui/Reveal).
- Those 46 routes therefore ship about 25 KB gzipped of duplicated JavaScript.
Attribution
Clean-worktree production builds, counting motion-runtime chunks on /vulnerability-remediation:
| Commit |
Copies |
Route size |
0dcb7ce9 last green |
1 |
319.3 KB |
e737c0f2 Impact Estimator rename |
1 |
319.3 KB |
559a0984 compare page rebuild |
1 |
319.3 KB |
d61c7ce0 gauge glyph |
1 |
319.3 KB |
cb7448bf platform page removal |
2 |
344.8 KB |
cb7448bf touches no motion imports (git diff 0dcb7ce9..HEAD -- apps/web/src | grep motion shows only a moved import line). Removing that route changed the set of routes sharing the motion modules, and Turbopack's chunk grouping responded by duplicating them rather than keeping one shared chunk.
Decision so far
PR #258 was merged past the failing ratchet with this issue as the tracker, rather than re-baselining and hiding the cost.
To resolve
- Work out why Turbopack duplicates the module group after the route removal (chunk-merging heuristic, or two chunk groups both claiming the modules) and whether a config or import-structure change restores one shared chunk.
- Until then the ratchet will fail on every web CI run. If the duplication is accepted, re-baseline with
UPDATE_BUNDLE_BASELINE=1 pnpm --filter @cleanstart/web bundle:budget against a production server and say so in the commit.
Repro
NEXT_PUBLIC_CMS_URL=https://cms.cleanstart.com pnpm --filter @cleanstart/web build
cd apps/web && grep -o 'src="[^"]*"' .next/server/app/vulnerability-remediation.html | grep _next | wc -l # 18, was 17
Then gzip each chunk and grep two of them for whileInView.
Symptom
The bundle-budget ratchet fails on
developmentsincecb7448bf("remove the unfinished CleanStart Platform page"):/vulnerability-remediationgrew from 317.8 KB to 345.3 KB gzipped (+27.5 KB, tolerance 5 KB). Absolute budgets are warn-only, so only the ratchet blocks.Cause
Turbopack now emits the framer-motion runtime twice in production. Two chunks (
0enzg3fle.a7y.jsand0bhimso_.o1iv.jsin the current build) carry the same modules: every marker string (whileInView,onViewportEnter,whileHover,whileTap,layoutId,keyframes,spring,inertia,prefers-reduced-motion) appears with identical counts in both, and sampled content similarity is 0.97.FadeUpin the layout tree).components/ui/Reveal).Attribution
Clean-worktree production builds, counting motion-runtime chunks on
/vulnerability-remediation:0dcb7ce9last greene737c0f2Impact Estimator rename559a0984compare page rebuildd61c7ce0gauge glyphcb7448bfplatform page removalcb7448bftouches no motion imports (git diff 0dcb7ce9..HEAD -- apps/web/src | grep motionshows only a moved import line). Removing that route changed the set of routes sharing the motion modules, and Turbopack's chunk grouping responded by duplicating them rather than keeping one shared chunk.Decision so far
PR #258 was merged past the failing ratchet with this issue as the tracker, rather than re-baselining and hiding the cost.
To resolve
UPDATE_BUNDLE_BASELINE=1 pnpm --filter @cleanstart/web bundle:budgetagainst a production server and say so in the commit.Repro
Then gzip each chunk and grep two of them for
whileInView.