Repository navigation
perf(build): look up action owner modules once per build pass - #3415
Merged
james-elicx merged 1 commit intoSep 24, 2026
Merged
james-elicx merged 1 commit into
james-elicx merged 1 commit into
Conversation
Action owner reachability walks the final module graph once per route. Each walk called Rolldown's getModuleInfo() for every visited module, and the client pass awaited this.resolve() for every client reference of every route. On a 380-route app that was 3.3M getModuleInfo calls and 13,920 serial resolves, adding ~16s to the rsc and client builds. Memoize module info by id and resolved client reference ids by import id for the duration of each helper call. The walks and the manifest output are unchanged. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01AZV1vkLWA62r59W1fa1AbL
Member
|
/bigbonk review for issues |
@vinext/cloudflare
create-vinext-app
@vinext/types
vinext
@cloudflare/workers-response-store
commit: |
Contributor
|
LGTM! |
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.
Fixes #3414
Since #2520, the action owner manifest pass walks the final module graph once per route. Each walk called Rolldown's
getModuleInfo()for every module it visited, and the client pass awaitedthis.resolve()for every client reference of every route. On a 380-route App Router app that meant 3.3MgetModuleInfocalls and 13,920 serial resolves, adding ~16s to the rsc and client builds.Change
In
packages/vinext/src/build/action-owner-manifest.ts:collectRscActionReachabilityandaddClientActionReachabilitywrapgetModuleInfoin a per-call memo keyed by module id (null results are cached too).resolveClientReferenceImportIdscaches resolved, canonicalized ids by import id across routes. The plugin resolves without an importer, so the result does not depend on the route.Both caches live only for one helper call inside one
generateBundle, so there is nothing to invalidate. The per-route walks, their order, and the manifest output are unchanged.Results
Our app (380 routes, ~10.2k client modules),
vinext build, Apple M4 Max:Inside the hook (instrumented locally on 0736fdd): rsc 4.8s -> 0.23s (1,239,421 -> 3,806
getModuleInfocalls); client 11.7s -> 1.0s (2,071,417 -> 10,167getModuleInfocalls, 13,920 -> 202 resolves).The generated
__vinext_action_owner_manifest.jsis byte-identical between main and this PR. The rest ofdisthas the same file list and the same content once content hashes, per-build random values (build id, revalidate secret) and the vinext install path are normalized. The install path differed only because the two builds installed vinext from differently named local tarballs; it feeds the client reference ids of vinext's own shims, which in turn change some key ordering and one quoted object key.Tests
tests/action-owner-manifest.test.ts: 50 routes sharing a layout, a page component, a client reference and actions. It asserts the manifest and thatgetModuleInfoandresolverun once per unique id. It fails on main (250 lookups instead of 54).vp test run tests/action-owner-manifest.test.ts tests/entry-templates.test.ts: 74 passed.pnpm run check: passes.tests/e2e/app-router/action-owner-production.browser.spec.ts(app-router-chrome-browser-specific): 24 passed and 1 failed, the same as on main. The failing "keeps offline-computable production action ids harmless" test is macOS-only:os.tmpdir()is a/var/folderssymlink while the test hashes a realpath under/private/var, so the expected id does not match. This PR does not change that.