Skip to content

perf(router-core): compact navigation parameter resolution - #8328

Merged
schiller-manuel merged 1 commit into
optimize-link-segment-interpolationfrom
optimize-link-navigation-params
Sep 13, 2026
Merged

perf(router-core): compact navigation parameter resolution#8328
schiller-manuel merged 1 commit into
optimize-link-segment-interpolationfrom
optimize-link-navigation-params

Conversation

@schiller-manuel

@schiller-manuel schiller-manuel commented Sep 9, 2026

Copy link
Copy Markdown
Collaborator

🎯 Changes

Reduce duplication in navigation parameter handling while preserving inheritance, null-prototype dictionaries, and updater isolation.

This is PR 5 of a stacked series and is based on optimize-link-segment-interpolation.

✅ Checklist

  • I have followed the steps in the Contributing guide.
  • I have tested code changes locally with the relevant test commands.
  • I fully understand the code in this pull request, including any code generated with AI assistance.

🚀 Release Impact

  • This change affects published code, and I have generated changesets.
  • This change is docs/CI/dev-only.

Summary by CodeRabbit

  • Bug Fixes

    • Prevented navigation parameter updates from leaking between location-building calls.
    • Preserved existing parameters when inheritance is requested.
    • Correctly clears optional parameters when explicitly disabled.
    • Ensured parameter values exposed through getters are read only once per update.
  • Tests

    • Added coverage for parameter inheritance, clearing, updater isolation, and getter access behavior.

@coderabbitai

coderabbitai Bot commented Sep 9, 2026

Copy link
Copy Markdown
Contributor

Review Change StackReview Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Advanced

Run ID: 89d20c9a-cc2f-4750-8bda-744b4a9bee3c

📥 Commits

Reviewing files that changed from the base of the PR and between 8520613 and 37e235f.

📒 Files selected for processing (1)
  • packages/router-core/src/router.ts
🚧 Files skipped from review as they are similar to previous changes (1)
  • packages/router-core/src/router.ts

Included review availability: Your plan provides up to 10 included reviews per hour; 8 remain after this review.


📝 Walkthrough

Walkthrough

The router consolidates navigation parameter resolution in resolveNextParams. The change preserves inheritance and null-prototype objects while isolating updater mutations. New tests cover repeated updater calls, optional parameter clearing, inherited parameters, and getter access.

Changes

Navigation parameter resolution

Layer / File(s) Summary
Parameter resolution helper
packages/router-core/src/router.ts
resolveNextParams handles inherited, cleared, object, and function parameter specifications in one location.
Parameter resolution validation
packages/router-core/tests/build-location.test.ts, .changeset/quick-otters-switch.md
Tests verify updater isolation, parameter inheritance, optional parameter clearing, and single getter access. The changeset records a patch release for @tanstack/router-core.

Priority: ⬇️ Low

Estimated code review effort: 2 (Simple) | ~10 minutes

Change: Refactor

Suggested reviewers: sheraff

Merge Risk: ⚪ Minimal · up to 37e23

The parameter-resolution consolidation has no identified merge-blocking risk in the supplied changes.

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 5 functions across 2 files. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and concisely describes the main change: compacting navigation parameter resolution in router-core.
Description check ✅ Passed The description includes the required Changes, Checklist, and Release Impact sections. It states the motivation, confirms testing and review requirements, and records the generated changeset for publi…
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
  • Fix all pre-merge checks with AI
✨ Finishing Touches 💡 1
📝 Generate docstrings 💡
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch optimize-link-navigation-params

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@github-actions

github-actions Bot commented Sep 9, 2026

Copy link
Copy Markdown
Contributor

🚀 Changeset Version Preview

6 package(s) bumped directly, 18 bumped as dependents.

🟩 Patch bumps

Package Version Reason
@tanstack/history 1.162.3 → 1.162.4 Changeset
@tanstack/react-router 1.170.35 → 1.170.36 Changeset
@tanstack/router-core 1.171.29 → 1.171.30 Changeset
@tanstack/solid-router 1.170.33 → 1.170.34 Changeset
@tanstack/start-server-core 1.169.34 → 1.169.35 Changeset
@tanstack/vue-router 1.170.32 → 1.170.33 Changeset
@tanstack/react-start 1.168.52 → 1.168.53 Dependent
@tanstack/react-start-client 1.168.33 → 1.168.34 Dependent
@tanstack/react-start-rsc 0.1.51 → 0.1.52 Dependent
@tanstack/react-start-server 1.167.40 → 1.167.41 Dependent
@tanstack/router-cli 1.167.35 → 1.167.36 Dependent
@tanstack/router-generator 1.167.35 → 1.167.36 Dependent
@tanstack/router-plugin 1.168.37 → 1.168.38 Dependent
@tanstack/router-vite-plugin 1.167.37 → 1.167.38 Dependent
@tanstack/solid-start 1.168.50 → 1.168.51 Dependent
@tanstack/solid-start-client 1.168.32 → 1.168.33 Dependent
@tanstack/solid-start-server 1.167.39 → 1.167.40 Dependent
@tanstack/start-client-core 1.170.29 → 1.170.30 Dependent
@tanstack/start-plugin-core 1.171.42 → 1.171.43 Dependent
@tanstack/start-static-server-functions 1.167.34 → 1.167.35 Dependent
@tanstack/start-storage-context 1.167.31 → 1.167.32 Dependent
@tanstack/vue-start 1.168.49 → 1.168.50 Dependent
@tanstack/vue-start-client 1.167.35 → 1.167.36 Dependent
@tanstack/vue-start-server 1.167.39 → 1.167.40 Dependent

@nx-cloud

nx-cloud Bot commented Sep 9, 2026

Copy link
Copy Markdown
Contributor

View your CI Pipeline Execution ↗ for commit 37e235f

Command Status Duration Result
nx run-many --target=build --exclude=examples/*... ✅ Succeeded 1m 30s View ↗

☁️ Nx Cloud last updated this comment at 2026-09-12 21:55:08 UTC

@github-actions

github-actions Bot commented Sep 9, 2026

Copy link
Copy Markdown
Contributor

Bundle Size Benchmarks

  • Commit: 74fb1b362672
  • Measured at: 2026-09-12T22:00:15.139Z
  • Baseline source: history:ae6853592904
  • Dashboard: bundle-size history

The following scenarios have bundle-size changes compared with the baseline:

Scenario Current (gzip) Initial (gzip) Raw Brotli Trend
react-router.minimal 84.0 KiB
+64 B
83.9 KiB
+63 B
262.2 KiB
-143 B
73.2 KiB
-9 B
█████▁▁▁▁▁▁▅
react-router.full 87.5 KiB
+62 B
87.4 KiB
+62 B
273.9 KiB
-143 B
76.3 KiB
+102 B
█████▂▂▂▂▂▁▅
solid-router.minimal 33.5 KiB
+68 B
33.4 KiB
+67 B
96.6 KiB
-117 B
30.3 KiB
+70 B
▁▂▂▂▂▂▂▂▂▂▁█
solid-router.full 38.4 KiB
+78 B
38.2 KiB
+76 B
111.3 KiB
-117 B
34.6 KiB
+135 B
▁▂▂▂▂▂▂▂▂▂▁█
vue-router.minimal 49.6 KiB
-10 B
49.4 KiB
-9 B
137.8 KiB
-545 B
44.8 KiB
-36 B
█████▁▁▁▁▁▁▁
vue-router.full 55.2 KiB
-17 B
55.0 KiB
-15 B
156.0 KiB
-545 B
49.8 KiB
-24 B
█████▁▁▁▁▁▁▁
react-start.minimal 96.9 KiB
+64 B
96.8 KiB
+62 B
304.4 KiB
-144 B
84.0 KiB
-15 B
█████▁▁▁▁▁▁▄
react-start.query-integration 104.3 KiB
+57 B
104.1 KiB
+54 B
330.9 KiB
-144 B
90.4 KiB
+87 B
█████▁▁▁▁▁▁▄
react-start.deferred-hydration 97.7 KiB
+63 B
96.8 KiB
+63 B
305.8 KiB
-144 B
84.6 KiB
-93 B
█████▁▁▁▁▁▁▄
react-start.full 100.1 KiB
+60 B
100.0 KiB
+63 B
314.2 KiB
-144 B
86.8 KiB
+37 B
█████▁▁▁▁▁▁▄
react-start.rsbuild.minimal 100.2 KiB
+48 B
100.0 KiB
+48 B
314.7 KiB
-126 B
86.5 KiB
+4 B
█████▁▁▁▁▁▁▄
react-start.rsbuild.minimal-iife 100.6 KiB
+47 B
100.4 KiB
+47 B
315.7 KiB
-126 B
86.8 KiB
+32 B
█████▁▁▁▁▁▁▃
react-start.rsbuild.full 103.5 KiB
+43 B
103.3 KiB
+43 B
324.8 KiB
-126 B
89.1 KiB
-61 B
█████▁▁▁▁▁▁▃
solid-start.minimal 46.4 KiB
+76 B
46.3 KiB
+75 B
137.8 KiB
-117 B
41.3 KiB
+125 B
▂▁▁▁▁▁▁▁▁▁▁█
solid-start.deferred-hydration 49.5 KiB
+69 B
46.4 KiB
+71 B
145.1 KiB
-117 B
44.0 KiB
+63 B
▁▂▂▂▂▂▂▂▂▂▂█
solid-start.full 51.5 KiB
+89 B
51.3 KiB
+88 B
153.2 KiB
-117 B
45.6 KiB
+76 B
▁▁▁▁▁▁▁▁▁▁▁█
vue-start.minimal 65.7 KiB
-30 B
65.6 KiB
-28 B
188.7 KiB
-545 B
58.6 KiB
+104 B
█████▂▂▂▂▂▂▁
vue-start.full 69.6 KiB
0 B
69.4 KiB
+2 B
201.0 KiB
-545 B
61.8 KiB
+36 B
█████▁▁▁▁▁▁

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.

@pkg-pr-new

pkg-pr-new Bot commented Sep 9, 2026

Copy link
Copy Markdown
More templates

@tanstack/arktype-adapter

npm i https://pkg.pr.new/@tanstack/arktype-adapter@8328

@tanstack/eslint-plugin-router

npm i https://pkg.pr.new/@tanstack/eslint-plugin-router@8328

@tanstack/eslint-plugin-start

npm i https://pkg.pr.new/@tanstack/eslint-plugin-start@8328

@tanstack/history

npm i https://pkg.pr.new/@tanstack/history@8328

@tanstack/nitro-v2-vite-plugin

npm i https://pkg.pr.new/@tanstack/nitro-v2-vite-plugin@8328

@tanstack/react-router

npm i https://pkg.pr.new/@tanstack/react-router@8328

@tanstack/react-router-devtools

npm i https://pkg.pr.new/@tanstack/react-router-devtools@8328

@tanstack/react-router-ssr-query

npm i https://pkg.pr.new/@tanstack/react-router-ssr-query@8328

@tanstack/react-start

npm i https://pkg.pr.new/@tanstack/react-start@8328

@tanstack/react-start-client

npm i https://pkg.pr.new/@tanstack/react-start-client@8328

@tanstack/react-start-rsc

npm i https://pkg.pr.new/@tanstack/react-start-rsc@8328

@tanstack/react-start-server

npm i https://pkg.pr.new/@tanstack/react-start-server@8328

@tanstack/router-cli

npm i https://pkg.pr.new/@tanstack/router-cli@8328

@tanstack/router-core

npm i https://pkg.pr.new/@tanstack/router-core@8328

@tanstack/router-devtools

npm i https://pkg.pr.new/@tanstack/router-devtools@8328

@tanstack/router-devtools-core

npm i https://pkg.pr.new/@tanstack/router-devtools-core@8328

@tanstack/router-generator

npm i https://pkg.pr.new/@tanstack/router-generator@8328

@tanstack/router-plugin

npm i https://pkg.pr.new/@tanstack/router-plugin@8328

@tanstack/router-ssr-query-core

npm i https://pkg.pr.new/@tanstack/router-ssr-query-core@8328

@tanstack/router-utils

npm i https://pkg.pr.new/@tanstack/router-utils@8328

@tanstack/router-vite-plugin

npm i https://pkg.pr.new/@tanstack/router-vite-plugin@8328

@tanstack/solid-router

npm i https://pkg.pr.new/@tanstack/solid-router@8328

@tanstack/solid-router-devtools

npm i https://pkg.pr.new/@tanstack/solid-router-devtools@8328

@tanstack/solid-router-ssr-query

npm i https://pkg.pr.new/@tanstack/solid-router-ssr-query@8328

@tanstack/solid-start

npm i https://pkg.pr.new/@tanstack/solid-start@8328

@tanstack/solid-start-client

npm i https://pkg.pr.new/@tanstack/solid-start-client@8328

@tanstack/solid-start-server

npm i https://pkg.pr.new/@tanstack/solid-start-server@8328

@tanstack/start-client-core

npm i https://pkg.pr.new/@tanstack/start-client-core@8328

@tanstack/start-fn-stubs

npm i https://pkg.pr.new/@tanstack/start-fn-stubs@8328

@tanstack/start-plugin-core

npm i https://pkg.pr.new/@tanstack/start-plugin-core@8328

@tanstack/start-server-core

npm i https://pkg.pr.new/@tanstack/start-server-core@8328

@tanstack/start-static-server-functions

npm i https://pkg.pr.new/@tanstack/start-static-server-functions@8328

@tanstack/start-storage-context

npm i https://pkg.pr.new/@tanstack/start-storage-context@8328

@tanstack/valibot-adapter

npm i https://pkg.pr.new/@tanstack/valibot-adapter@8328

@tanstack/virtual-file-routes

npm i https://pkg.pr.new/@tanstack/virtual-file-routes@8328

@tanstack/vue-router

npm i https://pkg.pr.new/@tanstack/vue-router@8328

@tanstack/vue-router-devtools

npm i https://pkg.pr.new/@tanstack/vue-router-devtools@8328

@tanstack/vue-router-ssr-query

npm i https://pkg.pr.new/@tanstack/vue-router-ssr-query@8328

@tanstack/vue-start

npm i https://pkg.pr.new/@tanstack/vue-start@8328

@tanstack/vue-start-client

npm i https://pkg.pr.new/@tanstack/vue-start-client@8328

@tanstack/vue-start-server

npm i https://pkg.pr.new/@tanstack/vue-start-server@8328

@tanstack/zod-adapter

npm i https://pkg.pr.new/@tanstack/zod-adapter@8328

commit: 37e235f

@schiller-manuel
schiller-manuel changed the base branch from optimize-link-state-correctness to optimize-link-segment-interpolation September 9, 2026 23:23
@schiller-manuel
schiller-manuel force-pushed the optimize-link-navigation-params branch from 676305d to 6ef0535 Compare September 9, 2026 23:23

@nx-cloud nx-cloud Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Important

At least one additional CI pipeline execution has run since the conclusion below was written and it may no longer be applicable.

Nx Cloud has identified a possible root cause for your failed CI:

We determined this failure is not related to the PR's code changes, which are scoped entirely to @tanstack/router-core. The error originates in a compiled dist artifact (e2e/e2e-utils/dist/esm/index.js) where a required export is missing, indicating the e2e-utils package was not built or has a stale build in this CI environment. Re-running the pipeline after a clean build of the e2e-utils package should resolve this.

No code changes were suggested for this issue.

Trigger a rerun:

Rerun CI

Nx Cloud View detailed reasoning on Nx Cloud ↗


🎓 Learn more about Self-Healing CI on nx.dev

@codspeed-hq

codspeed-hq Bot commented Sep 10, 2026

Copy link
Copy Markdown

Merging this PR will not alter performance

✅ 180 untouched benchmarks


Comparing optimize-link-navigation-params (37e235f) with optimize-link-segment-interpolation (2029bb3)

Open in CodSpeed

@schiller-manuel
schiller-manuel force-pushed the optimize-link-navigation-params branch from 6ef0535 to 81f8a8a Compare September 10, 2026 20:29

@Sheraff Sheraff left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i trust the benchmarks, there isn't much to review here

@schiller-manuel
schiller-manuel force-pushed the optimize-link-navigation-params branch from 81f8a8a to 8520613 Compare September 10, 2026 21:12
@schiller-manuel
schiller-manuel added this pull request to stack #8346 September 10, 2026 21:30
@schiller-manuel
schiller-manuel force-pushed the optimize-link-navigation-params branch from 8520613 to 597c134 Compare September 11, 2026 21:08
Declare the native null-prototype target once for non-inheriting parameter modes. Preserve updater isolation, native copy counts, and literal-parameter merge behavior. Group parameter resolution with search middleware without changing Link or path interpolation logic.

Official current-branch bundles shrink in all 18 scenarios by 2-30 gzip bytes versus 9c7cab4. React Router minimal: 85778 -> 85748 (-30); full: 89386 -> 89384 (-2).

A matched-main preview against cf166d1 measures React Router minimal at 85805 versus main 85821 (-16), and full at 89385 versus main 89398 (-13). Eight of nine matched-main React fixtures meet main; Start+Query remains +25 bytes. Small Solid overages are retained as agreed.

Eight paired client/SSR cases with four independent replicas each detected no supported timing regression or improvement. Add coverage for fresh updater copies, null prototypes, inheritance, and clearing.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
@schiller-manuel
schiller-manuel force-pushed the optimize-link-navigation-params branch from 597c134 to 37e235f Compare September 12, 2026 21:35
@schiller-manuel
schiller-manuel merged commit f151ab0 into main Sep 13, 2026
25 of 26 checks passed
@schiller-manuel
schiller-manuel deleted the optimize-link-navigation-params branch September 13, 2026 11:55
Sheraff pushed a commit that referenced this pull request Sep 14, 2026
Declare the native null-prototype target once for non-inheriting parameter modes. Preserve updater isolation, native copy counts, and literal-parameter merge behavior. Group parameter resolution with search middleware without changing Link or path interpolation logic.

Official current-branch bundles shrink in all 18 scenarios by 2-30 gzip bytes versus 9c7cab4. React Router minimal: 85778 -> 85748 (-30); full: 89386 -> 89384 (-2).

A matched-main preview against cf166d1 measures React Router minimal at 85805 versus main 85821 (-16), and full at 89385 versus main 89398 (-13). Eight of nine matched-main React fixtures meet main; Start+Query remains +25 bytes. Small Solid overages are retained as agreed.

Eight paired client/SSR cases with four independent replicas each detected no supported timing regression or improvement. Add coverage for fresh updater copies, null prototypes, inheritance, and clearing.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants