Simplify loader flight and render acknowledgement ownership - #7926
Simplify loader flight and render acknowledgement ownership#7926Sheraff wants to merge 3 commits into
Conversation
|
Important Review skippedAuto reviews are disabled on base/target branches other than the default branch. Please check the settings in the CodeRabbit UI or the ⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Plus Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
|
View your CI Pipeline Execution ↗ for commit 626bd62
☁️ Nx Cloud last updated this comment at |
🚀 Changeset Version Preview4 package(s) bumped directly, 19 bumped as dependents. 🟩 Patch bumps
|
Bundle Size Benchmarks
The following scenarios have bundle-size changes compared with the baseline:
Current gzip tracks all emitted client JS chunks. Initial gzip tracks only the entry/import graph. Trend sparkline is historical current gzip ending with this PR measurement; lower is better. |
Merging this PR will regress 12 benchmarks
|
| Mode | Benchmark | BASE |
HEAD |
Efficiency | |
|---|---|---|---|---|---|
| ❌ | Memory | mem server error-paths unmatched (react) |
262.7 KB | 604.3 KB | -56.53% |
| ❌ | Memory | mem server serialization-payload (vue) |
3.5 MB | 6.1 MB | -42.46% |
| ❌ | Memory | mem server error-paths not-found (vue) |
329.3 KB | 420.2 KB | -21.62% |
| ❌ | Memory | mem client navigation-churn (react) |
442 KB | 542.2 KB | -18.47% |
| ❌ | Memory | mem server error-paths not-found (solid) |
414.9 KB | 459.4 KB | -9.7% |
| ❌ | Simulation | ssr server-fn not-found (solid) |
61.8 ms | 66.8 ms | -7.5% |
| ❌ | Memory | mem client navigation-churn (solid) |
497 KB | 536.2 KB | -7.3% |
| ❌ | Simulation | ssr server-fn POST (solid) |
64.7 ms | 69.5 ms | -6.9% |
| ❌ | Memory | mem server peak-large-page (vue) |
784.5 KB | 835.4 KB | -6.09% |
| ❌ | Simulation | ssr server-fn send-context (solid) |
65.9 ms | 69.6 ms | -5.34% |
| ❌ | Simulation | ssr server-fn GET (solid) |
70.6 ms | 74.3 ms | -4.88% |
| ❌ | Memory | mem server server-fn-churn (solid) |
264.5 KB | 274.8 KB | -3.76% |
| ⚡ | Memory | mem server server-fn-churn (vue) |
4,139.7 KB | 263.7 KB | ×16 |
| ⚡ | Memory | mem server error-paths redirect (solid) |
777.5 KB | 283.1 KB | ×2.7 |
| ⚡ | Memory | mem client unique-location-churn (solid) |
598.8 KB | 342.3 KB | +74.95% |
| ⚡ | Memory | mem client interrupted-navigations (react) |
409.3 KB | 251.6 KB | +62.66% |
| ⚡ | Memory | mem server serialization-payload (react) |
5.2 MB | 3.2 MB | +61.84% |
| ⚡ | Memory | mem server request-churn (react) |
653 KB | 498.1 KB | +31.09% |
| ⚡ | Memory | mem client interrupted-navigations (solid) |
403.7 KB | 340.6 KB | +18.53% |
| ⚡ | Memory | mem server error-paths redirect (vue) |
351.7 KB | 303.4 KB | +15.89% |
| ... | ... | ... | ... | ... | ... |
ℹ️ Only the first 20 benchmarks are displayed. Go to the app to view all benchmarks.
Tip
Investigate this regression by commenting @codspeedbot fix this regression on this PR, or directly use the CodSpeed MCP with your agent.
Comparing codex/simplify-match-loading-orchestration (270f2f9) with fix-router-core-lane-match-loader (b8204ea)
Summary
This stacks on #7805 and simplifies its match-loading rewrite around one rule: each match ID has at most one discoverable loader generation, each flight has one normalized outcome, and lane ownership decides where that outcome may publish.
The change closes the supported orchestration races selected from #7911 without adding another flag, counter, deadline, or completion promise. After the final automated formatting pass, the production diff is
+153/-173lines (net-20).Architecture
beforeLoadcontextualization, before the async frame yields. This removes the zero-owner handoff gap without a retry loop.errorandnotFound.onError-reentrant navigation starts a fresh generation._preloadscontroller entry rather than an unrelated foreground_tx.pendingComponentfinishes its own preload; route success still waits for the normal component. The correction moves the existing chunk wake-up earlier rather than adding another offer or authority.The resulting authorities are deliberately narrow:
_txowns foreground publication._preloadsowns speculative cancellation and private redirect continuation.The lazy pending callback is internal.
RouterCore.loadRouteChunkretains its previous two-argument public type.Intentional semantics and compromises
beforeLoad; its context and control flow remain lane-local.shouldReload: truerequires a loader generation but does not bypass discoverable same-ID work. The active-flight overlap is otherwise undefined; using the uniform rule preserves the relevantmainbehavior and removes bytes.errorornotFound. A navigation planned after the terminal flight has retired retries normally.invalidate()reruns planning andbeforeLoad, but does not introduce matches owned only by an active speculative preload as a second invalidation/admission authority. Same-ID loader work owned only by that preload can remain discoverable and reusable, including its old-context value.pendingMsor rebase apendingMinMsdeadline that an exact render acknowledgement has already established. If the replacement supersedes an unacknowledged offer, its own exact acknowledgement establishes the minimum-visible deadline under the existing receipt rules.How #7911 was integrated
#7911, the independent audit, and the proposed mechanism were used as sources of candidate specifications and reproductions, not adopted wholesale.
Adopted or reformulated
errorandnotFoundare shared with an already-joined navigation. The final tests use deterministic public-API gates.mainregression where the body is fresh but the head/title remains stale. Unlike the React receipt test, this is a demonstratedmainregression.Corrected to match supported behavior
mainsemantics: one active same-ID parent loader may serve multiple successors, including its old-context value, whileloaderDeps-keyed child loaders supersede normally.onErrorreceives a fresh generation because the terminal flight is retired before callbacks.beforeLoad.Intentionally not adopted
_refreshRoutebehavior.shouldReload: trueto duplicate active same-ID loader work.beforeLoadcontext.main, redundant cases, and probes that required mutating internals.Size and performance
Compared with the exact base commit
b8204ea9ad:react-router.minimal:-67 Bgzip,-65 Binitial gzip,-227 Braw, and-73 BBrotli.solid-router.minimal:-13 Bgzip,-13 Binitial gzip,-92 Braw, and+24 BBrotli.6–88 B, with no JS chunk-count changes.-622 Bgzip,-622 Binitial gzip,-2,539 Braw, and-941 BBrotli.The Solid CI correction costs
31 Bgzip inreact-router.minimal,29 Binsolid-router.minimal, and598 Bsummed across the 17 scenarios relative to the first PR revision. Several equivalent phase implementations were measured and rejected; the retained callback-threaded version ties for the smallest gzip result that also waits for the pending component's own framework preload, while keeping the better Brotli result and clearer source. The complete PR remains smaller than the exact base in every gzip scenario.Three individual scenario totals have small Brotli increases despite raw and gzip improvements; aggregate Brotli decreases and no chunks are added.
Focused runtime benchmarks on the first PR revision showed no regression signal. The lazy-phase follow-up moves an existing notification on a path those workloads do not exercise:
-0.16%,-0.11%, and+0.24%throughput).1.13%with mean time down1.12%.1.85%with mean time down1.81%.Validation
git diff --checkpassed.