Ship one copy of each WebAssembly runtime instead of seven - #182
Conversation
Two utility apps bundle the same 48 MB OpenCascade build and seven bundle replicad, so every deployment carried ~149 MB of byte-identical files. On top of that, webstep-viewer kept a second copy of OpenCascade next to its assets/ directory that nothing loads: its worker resolves the file relative to import.meta.url, which lands in assets/, and the sync script never wrote the root copy either. Build output drops from ~440 MB to 291 MB, so the 10 GB Hobby quota now holds ~34 deployments instead of 22. - Delete the unreferenced root copy in webstep-viewer (48 MB). - postbuild: keep one copy of each payload >= 1 MB under utility-apps/ and mini-games/, drop the rest (99.6 MB); vercel.json rewrites the deleted URLs to the copy that stays. HTML is never collapsed, since identical markup at two URLs is two real pages. - The script derives the rules from the build and fails when vercel.json is missing one, keeps one that stopped matching, or orders one after the locale static rewrite, which would shadow it. - Each rule carries its own optional locale prefix rather than relying on the locale rewrite feeding it, because only the first match applies. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Ao3WhHUZQ3z7Y5L1XHwMVN
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
Codex Review SummaryThis comment shows the latest Codex review activity on this pull request.
ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings. |
|
This pull request has been ignored for the connected project Preview Branches by Supabase. |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: eca7c7c6ec
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
The drift guard validated vercel.json against build/, the one tree the script mutates, so it had to tolerate a missing source to stay a no-op on a second run. An app rebuild that renames a formerly duplicated asset hit that same case: source gone, canonical destination still there, rule silently kept. Renames are how these hashed bundle names change, so the guard missed the drift it exists to catch. Derive the rules from static/ instead, which Docusaurus copies verbatim and which this script never touches. Validation is then a pure function of the committed tree and rejects any rule that is not a current duplicate, while the deletions skip what is already gone, so a second run is still a no-op. Also report the missing, stale and misordered rules together: a rename trips two of them at once, and the build takes minutes to reach here. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Ao3WhHUZQ3z7Y5L1XHwMVN
Follow-up to #180. That PR stopped each deployment shipping six locale copies of
static/(~2.1 GB → ~440 MB). This one removes the duplication that remains insidestatic/: ~440 MB → 291 MB.The duplication
The pre-built utility apps each bundle their own copy of the same WebAssembly runtimes:
opencascade.full-BROZOezB.wasm(48 MB)replicad_single-BXInhmaQ.wasm(10.3 MB)replicad_single-ko7rBbsE.wasm(10.4 MB)One of those copies is simply dead:
static/utility-apps/webstep-viewer/opencascade.full-BROZOezB.wasm, sitting next toassets/rather than in it. Nothing loads it —assets/worker-Br7ins6r.jsresolves the file withnew URL("opencascade.full-BROZOezB.wasm", import.meta.url), which lands insideassets/, where the real copy is.scripts/sync-webstep-viewer-embed.jsnever wrote the root copy either (it syncsassets/,app.htmland threeocct-*files), so it will not come back.Changes
webstep-viewer(48 MB out of the repo).scripts/dedupe-shared-assets.js, chained intopostbuildafterdedupe-locale-static.js: hashes every file ≥ 1 MB underutility-apps/andmini-games/, keeps the lexicographically first copy of each distinct payload and deletes the others frombuild/(99.6 MB);vercel.jsonrewrites the deleted URLs to the copy that stays..htmlis never collapsed — identical markup at two URLs is two real pages.vercel.json, placed above the locale static rewrite.Design notes
The rules are derived from
static/, which Docusaurus copies verbatim and which this script never touches; only the deletions look atbuild/. That keeps validation a pure function of the committed tree however often the script runs, so it can be strict: the build fails whenvercel.jsonis missing a rule, keeps one that is no longer a current duplicate, or orders one after the locale rewrite (first match wins, so such a rule would be shadowed for localized URLs). All three are reported together, since a rename trips two of them at once. The deletion loop skips what is already gone, so a second run over the same build is a no-op.Each rule carries its own optional locale prefix (
/:locale(ru|ua|de|es|et)?/…) instead of relying on the locale rewrite feeding into it, since only one rewrite applies per request.The 1 MB threshold covers 99.6 of the 100.2 MB of duplication with six rules; going lower would add ~15 rules for the last 0.6 MB.
Verification
pnpm buildgreen:Removed 2530 duplicated static files from locale builds (1447.9 MB).thenRemoved 6 duplicated app assets shared between utility apps (99.6 MB).A second run of the script reportsRemoved 0.build/, all six sources are gone.path-to-regexp:/utility-apps/qr-nameplate/assets/replicad_single-ko7rBbsE.wasmand/ru/…both resolve to theblind-flange-calculatorcopy;/ru/utility-apps/metal-bending/…and/ru/utility-apps/pdf-master/…still fall through to the existing locale rewrite;/ru/docs/intro/is untouched.vercel.json, a rule ordered after the locale rewrite, an asset renamed to a new content hash, and an asset deleted outright. Each fails the build with the offending rules printed; the rename reports both the stale rule and the missing one in the same run.pnpm lint0 errors (162 pre-existing warnings insrc/),pnpm typecheckclean.Note
As with the locale dedupe, the deleted URLs resolve through
vercel.jsonand so 404 underdocusaurus serve;pnpm startis unaffected.At 291 MB the 10 GB Hobby quota holds ~34 deployments instead of ~22. Setting a Deployment Retention policy for preview/canceled/errored deployments is still the lever that stops storage accumulating at all, and is not part of this PR.
🤖 Generated with Claude Code
https://claude.ai/code/session_01Ao3WhHUZQ3z7Y5L1XHwMVN