Fix default route component remounting - #8002
Conversation
|
Important Review skippedDraft detected. 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 9cb14ab
☁️ Nx Cloud last updated this comment at |
🚀 Changeset Version PreviewNo changeset entries found. Merging this PR will not cause a version bump for any packages. |
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 7 benchmarks
|
| Mode | Benchmark | BASE |
HEAD |
Efficiency | |
|---|---|---|---|---|---|
| ❌ | Memory | mem server error-paths unmatched (react) |
263.6 KB | 411.3 KB | -35.9% |
| ❌ | Simulation | client-rewrites navigation loop (vue) |
48.1 ms | 68.3 ms | -29.66% |
| ❌ | Simulation | client-history navigation loop (vue) |
41.1 ms | 51.1 ms | -19.59% |
| ❌ | Simulation | ssr dehydrate rich types (solid) |
87.3 ms | 99.8 ms | -12.47% |
| ❌ | Simulation | ssr dehydrate plain control (solid) |
119.6 ms | 129.5 ms | -7.68% |
| ❌ | Simulation | client-mount loop (vue) |
57.9 ms | 60.5 ms | -4.27% |
| ❌ | Memory | mem server error-paths not-found (vue) |
318.6 KB | 329.5 KB | -3.31% |
| ⚡ | Memory | mem client unique-location-churn (vue) |
984 KB | 384.6 KB | ×2.6 |
| ⚡ | Memory | mem server error-paths redirect (solid) |
588.2 KB | 283.5 KB | ×2.1 |
| ⚡ | Memory | mem client loader-data-retention (vue) |
982.1 KB | 641 KB | +53.22% |
| ⚡ | Simulation | client-nested-params navigation loop (vue) |
144.8 ms | 96.3 ms | +50.4% |
| ⚡ | Memory | mem client interrupted-navigations (vue) |
499.5 KB | 340.9 KB | +46.51% |
| ⚡ | Memory | mem client unique-location-churn (solid) |
341.6 KB | 236.2 KB | +44.66% |
| ⚡ | Memory | mem client interrupted-navigations (solid) |
341.5 KB | 242.8 KB | +40.63% |
| ⚡ | Memory | mem client loader-data-retention (solid) |
154.1 KB | 141.9 KB | +8.66% |
| ⚡ | Simulation | client-loaders navigation loop (vue) |
57.1 ms | 52.8 ms | +8.26% |
| ⚡ | Simulation | client-history navigation loop (solid) |
53.8 ms | 49.9 ms | +7.73% |
| ⚡ | Simulation | client-search-params navigation loop (solid) |
114.8 ms | 108 ms | +6.28% |
| ⚡ | Simulation | client-rewrites navigation loop (solid) |
76.3 ms | 73 ms | +4.52% |
| ⚡ | Memory | mem client navigation-churn (vue) |
1.2 MB | 1.2 MB | +4.43% |
| ... | ... | ... | ... | ... | ... |
ℹ️ 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/fix-default-route-remounting (9cb14ab) with main (c568caf)
Summary
Root cause
Solid used the changing match ID as its implicit component key when no
remountDepsfunction was configured. Vue independently included serialized strict params in the child Match key. Both identities changed during param-only navigation and forced active route components to unmount and mount again, contrary to the documented default.Removing Vue's implicit param key exposed a separate assumption in Link: it copied declared props during setup and therefore relied on its parent remounting to receive param-derived values. The first correctness fix kept those props live with
proxyRefs({ ...toRefs(props), ...attrs }).That proxy was also the source of the broad Vue CPU regressions. Link has several location-driven computed values, and every navigation caused each Link to repeatedly cross the proxy and unwrap refs. Link-heavy scenarios amplified that fixed per-Link cost, which is why otherwise unrelated Vue navigation simulations moved together.
The follow-up keeps correctness with a computed plain snapshot. The snapshot rebuilds only when Link inputs change; location-only updates reuse the cached object.
Impact
Param-only navigation now preserves component instances and local state by default in Solid and Vue, avoiding unnecessary lifecycle work and garbage collection. Applications can continue to opt into remounting with
remountDeps.The focused Vue links benchmark recovered from 31.04 ms with the proxy/ref implementation to 17.15 ms (±1.13%). A controlled run with the old non-reactive plain spread was 17.46 ms, so the cached reactive version is back at the prior CPU cost while retaining correct updates in reused components.
Validation
CI=1 NX_DAEMON=false pnpm nx run @benchmarks/client-nav:test:perf:vue --outputStyle=stream --skipRemoteCache -- scenarios/links/vue/speed.bench.tsgit diff --check