Skip to content

perf: reuse core Link dependency metadata in React and add focused client-nav benchmarks#6999

Draft
Sheraff wants to merge 6 commits intomainfrom
perf/react-link-location-deps
Draft

perf: reuse core Link dependency metadata in React and add focused client-nav benchmarks#6999
Sheraff wants to merge 6 commits intomainfrom
perf/react-link-location-deps

Conversation

@Sheraff
Copy link
Contributor

@Sheraff Sheraff commented Mar 20, 2026

Summary

  • Make React Link reuse core-generated location dependency metadata so it can skip unnecessary buildLocation work and avoid rebuilds on unrelated location updates.
  • Add a focused React client-nav benchmark for static-search links to measure the search-only invalidation case more directly.
  • Include investigation notes in link-performance-investigation.md covering the explored approaches, tradeoffs, correctness fix, and current understanding.

Benchmarks

  • Mixed React client-nav remains roughly flat to slightly worse versus main (-2.2% throughput in the measured run), so the broad benchmark does not yet show a general win.
  • The new targeted static-search benchmark is much faster when links opt into activeOptions={{ includeSearch: false }} (+65.2% throughput, -39.5% mean time).
  • The same targeted scenario is still modestly faster with the default activeOptions={{ includeSearch: true }} (+5.8% throughput, -5.4% mean time), showing that reusing cached next still helps even when active-state recomputation remains necessary.

Validation

  • Added React link tests covering skipped rebuilds on unrelated search changes and the inherited-param active-state regression found during the investigation.
  • Ran affected Nx validation for eslint, types, and unit tests, plus the React client-nav perf benchmark and bundle-size build.
  • Added investigation notes documenting commands, benchmark setup, measured results, and why this is being proposed as a draft PR.

Teach router-core to expose internal Link dependency metadata so React can reuse cached next locations during search-only churn. Add a focused benchmark and investigation notes so the targeted win can be measured against main.
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Mar 20, 2026

Important

Review skipped

Draft detected.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 8bc5ac5b-8b2b-476d-b125-9dbdec4c2c4a

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch perf/react-link-location-deps

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

@nx-cloud
Copy link

nx-cloud bot commented Mar 20, 2026

🤖 Nx Cloud AI Fix Eligible

An automatically generated fix could have helped fix failing tasks for this run, but Self-healing CI is disabled for this workspace. Visit workspace settings to enable it and get automatic fixes in future runs.

To disable these notifications, a workspace admin can disable them in workspace settings.


View your CI Pipeline Execution ↗ for commit 8b1ce03

Command Status Duration Result
nx affected --targets=test:eslint,test:unit,tes... ❌ Failed 15m 11s View ↗
nx run-many --target=build --exclude=examples/*... ✅ Succeeded 1m 52s View ↗

☁️ Nx Cloud last updated this comment at 2026-03-22 17:23:02 UTC

@github-actions
Copy link
Contributor

github-actions bot commented Mar 20, 2026

🚀 Changeset Version Preview

No changeset entries found. Merging this PR will not cause a version bump for any packages.

@github-actions
Copy link
Contributor

github-actions bot commented Mar 20, 2026

Bundle Size Benchmarks

  • Commit: b9f9ea15b696
  • Measured at: 2026-03-22T17:08:37.387Z
  • Baseline source: history:b9f9ea15b696
  • Dashboard: bundle-size history
Scenario Current (gzip) Delta vs baseline Raw Brotli Trend
react-router.minimal 88.65 KiB +509 B (+0.56%) 279.66 KiB 77.00 KiB ▁▁▁▇▇▇▇▇▇▅▅█
react-router.full 91.82 KiB +526 B (+0.56%) 290.39 KiB 79.67 KiB ▁▁▁▇▇▇▇▇▇▅▅█
solid-router.minimal 36.00 KiB +203 B (+0.55%) 108.87 KiB 32.35 KiB ███▃▃▃▃▃▃▁▁▂
solid-router.full 40.35 KiB +205 B (+0.50%) 122.01 KiB 36.13 KiB ███▃▃▃▃▃▃▁▁▂
vue-router.minimal 54.00 KiB +229 B (+0.42%) 155.11 KiB 48.43 KiB ▁▁▁██████▆▆▇
vue-router.full 58.78 KiB +238 B (+0.40%) 170.27 KiB 52.56 KiB ▁▁▁██████▆▆▇
react-start.minimal 103.00 KiB +572 B (+0.55%) 327.42 KiB 89.04 KiB ▁▁▁██████▄▄█
react-start.full 106.38 KiB +539 B (+0.50%) 337.72 KiB 91.83 KiB ▁▁▁██████▄▄█
solid-start.minimal 50.09 KiB +231 B (+0.45%) 155.06 KiB 44.07 KiB ███▃▃▃▃▃▃▁▁▂
solid-start.full 55.50 KiB +245 B (+0.43%) 170.90 KiB 48.81 KiB ███▄▄▄▄▄▄▁▁▂

Trend sparkline is historical gzip bytes ending with this PR measurement; lower is better.

@pkg-pr-new
Copy link

pkg-pr-new bot commented Mar 20, 2026

More templates

@tanstack/arktype-adapter

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

@tanstack/eslint-plugin-router

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

@tanstack/history

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

@tanstack/nitro-v2-vite-plugin

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

@tanstack/react-router

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

@tanstack/react-router-devtools

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

@tanstack/react-router-ssr-query

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

@tanstack/react-start

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

@tanstack/react-start-client

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

@tanstack/react-start-server

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

@tanstack/router-cli

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

@tanstack/router-core

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

@tanstack/router-devtools

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

@tanstack/router-devtools-core

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

@tanstack/router-generator

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

@tanstack/router-plugin

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

@tanstack/router-ssr-query-core

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

@tanstack/router-utils

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

@tanstack/router-vite-plugin

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

@tanstack/solid-router

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

@tanstack/solid-router-devtools

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

@tanstack/solid-router-ssr-query

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

@tanstack/solid-start

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

@tanstack/solid-start-client

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

@tanstack/solid-start-server

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

@tanstack/start-client-core

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

@tanstack/start-fn-stubs

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

@tanstack/start-plugin-core

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

@tanstack/start-server-core

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

@tanstack/start-static-server-functions

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

@tanstack/start-storage-context

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

@tanstack/valibot-adapter

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

@tanstack/virtual-file-routes

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

@tanstack/vue-router

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

@tanstack/vue-router-devtools

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

@tanstack/vue-router-ssr-query

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

@tanstack/vue-start

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

@tanstack/vue-start-client

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

@tanstack/vue-start-server

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

@tanstack/zod-adapter

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

commit: 8b1ce03

@codspeed-hq
Copy link

codspeed-hq bot commented Mar 20, 2026

Merging this PR will degrade performance by 42.51%

❌ 1 regressed benchmark
✅ 5 untouched benchmarks

⚠️ Please fix the performance issues or acknowledge them on CodSpeed.

Performance Changes

Benchmark BASE HEAD Efficiency
client-side navigation loop (react) 61.1 ms 106.3 ms -42.51%

Comparing perf/react-link-location-deps (8b1ce03) with main (b9f9ea1)

Open in CodSpeed

Sheraff added 5 commits March 21, 2026 00:02
Track only the current search keys and key-count information that active-state matching actually needs, so static search links can skip rerenders even with includeSearch enabled. Simplify buildLocation dependency collection and extend the React client-nav benchmark to measure both includeSearch modes.
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.

1 participant