Repository navigation
perf(wab): build token and image-asset dictionaries once per call - #659
Merged
Merged
Conversation
…t-dict-once-per-call # Conflicts: # docs/internal/UPSTREAM_MERGE_RUNBOOK.md # platform/wab/src/wab/server/__tests__/ep-fork-integrity.spec.ts
field123
approved these changes
Oct 5, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Closes #643, in the Branch merge performance milestone. The change lands on this fork first. After it proves itself here, it goes upstream to plasmicapp/plasmic as a separate PR.
On the server,
maybeComputedFnnever caches, so site invariants andcompareSitesrebuilt the all-deps token and image-asset dictionaries once per token, tpl or rule set.Final tokens are now classified with a set lookup per token instead of array scans.
toFinalTokentakes an optionalisMemberargument, and the final style token selectors passsetMembership()once per batch. Callers that pass nothing scan as before.Outputs do not change. The upstream-merge runbook and
ep-fork-integrity.spec.tslist the change, so that an upstream merge does not drop it.Evidence
compareSites, 3,459 per all-updatedtryMergeand 810 asset dictionary builds.compareSitestook 3.0–3.1 s,genSiteErrors3.2 s, and an all-updatedtryMerge13.9–15.0 s.After: 2 builds per
compareSites, 588 pertryMergeand 0 asset builds.compareSitestook 40–45 ms,genSiteErrors240–270 ms, andtryMerge7.3–8.1 s. A partialtryMergegoes from about 6.0 s to 4.7–4.9 s.compareSitesover 348 pairs goes from about 4.7 s to about 0.6 s,componentToUsedImageAssetsover 77 sites from about 2.6–3.0 s to about 0.12 s, andgenSiteErrorsfrom about 3.2–3.6 s to about 0.4 s. The small bundle merges are flat. The machine was loaded, so times are approximate.diff -rq): used tokens and assets andgenSiteErrorsover 77 sites, changelog JSON and release type over 348compareSitespairs, and 25tryMergeruns, in node and in jsdom with observable sites.compareSitespass before and after. The shared, site-diffs, model and bundler specs pass, andbranching.spec.tspasses 17 of 17 on Postgres 14.Merge Danger
Door: two-way
A revert restores the old code. There are no data, schema or API changes.
Blast Radius: publish, merge and invariants
compareSitesruns inpublishProject(up to three times per real merge),createBranchFromBase, webhooks and the Studio merge flow. Site invariants run intryMergeand in Studio. Each reused dictionary lives inside one synchronous call that only reads the site, so a future edit must keep those calls free of writes to tokens or image assets. No error path moves: on a corrupt dependency with no site,getValidRefswalks every dependency beforecomponentToUsedTokensruns, so the TypeError comes from the same place as before.