Skip to content

bench(client-nav): add React and Solid hydration scenarios - #8439

Merged
Sheraff merged 7 commits into
mainfrom
bench/react-client-hydration
Sep 25, 2026
Merged

Sheraff merged 7 commits into
mainfrom
bench/react-client-hydration

Conversation

@Sheraff

@Sheraff Sheraff commented Sep 15, 2026 •

Copy link
Copy Markdown
Collaborator

Changes

Add React and Solid hydration scenarios to the existing benchmarks/client-nav CodSpeed suite. These cover the gap between server rendering and client mounting/navigation, including post-hydration Link updates. The Vue scenario is split into #8498, which separately depends on #8440.

Workload and measurement

Each adapter restores three matched routes, three beforeLoad contexts, two loader results, 192 ordinary Links, and eight hash-sensitive Links. The server URL has no fragment; the client URL has #details, matching half of the hash-sensitive Links.

Static HTML and real Router SSR bootstrap scripts are generated during the build. Every invocation gets a fresh jsdom window and production client bundle instance. The measured region executes the payload, creates/restores the router through its public hydration API, and hydrates the existing DOM through the follow-up updates. Server rendering, HTML parsing, initial bundle evaluation, validation, and teardown are outside measurement.

  • React: await an explicit post-hydration completion signal and two idle scheduler turns, with a 60-second watchdog. Includes delayed-commit, delayed-scheduler, and watchdog regression tests.
  • Solid: execute the native hydration bootstrap, preserve component/key ordering, and await mount, rendered state, active-link effects, and idle turns. Check identity of every workload element to catch template fallback. Settlement is capped at 100 turns.

Both scenarios support CodSpeed suite hooks and Tinybench per-iteration hooks, with diagnostic render/reactivity counting confined to harness tests. Assertions cover restored data/context, zero client loader or beforeLoad calls, DOM reuse, hrefs/active state, event handlers, and fresh-state cleanup.

Wire both scenarios into their framework aggregate builds and the type-check graph; existing Vitest/CodSpeed discovery picks them up. Update benchmark documentation and increase the expected CPU result count from 132 to 134. Generated HTML and bundles remain build artifacts. The React and Solid scenario files are unchanged by the split.

Validation

  • pnpm format and git diff --check pass.
  • Nx hydration test:unit: React 6/6 and Solid 3/3 pass.
  • Nx hydration test:types:client and dependency/client fixture builds pass for both frameworks.
  • Validated on Node 24.8.0 / pnpm 11.21.0.
  • Verified only React/Solid hydration remains in this PR's scenario files and aggregate build/type-check wiring.

Local wall-time results are not used to claim a performance gain. Instrumented performance runs were not rerun for this split.

Release impact

Dev-only benchmark changes; no changeset required.

Summary by CodeRabbit

  • New Features
    • Added client-navigation hydration benchmarks for React and Solid, including checks for restored route data and navigation behavior.
  • Updates
    • Vue hydration is no longer included in the client-navigation benchmark scenarios.
    • Updated the benchmark documentation to reflect the supported hydration frameworks and scenarios.
    • Adjusted the expected CPU result count per repetition from 135 to 134.

@nx-cloud

nx-cloud Bot commented Sep 15, 2026 •

Copy link
Copy Markdown
Contributor

View your CI Pipeline Execution ↗ for commit 17aef64

Command Status Duration Result
nx affected --targets=test:eslint,test:unit,tes... ✅ Succeeded 2m 22s View ↗
nx run-many --target=build --exclude=examples/*... ✅ Succeeded 1m 24s View ↗

☁️ Nx Cloud last updated this comment at 2026-09-25 15:51:45 UTC

@coderabbitai

coderabbitai Bot commented Sep 15, 2026 •

Copy link
Copy Markdown
Contributor

Review in Change Stack →

Navigate logical layers of code changes, visualize relationships, and explore their blast radius.

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Repository: TanStack/router/.coderabbit.yaml

Review profile: CHILL

Plan: Advanced

Run ID: 290669cb-0030-4615-b169-edc18ec08574

📥 Commits

Reviewing files that changed from the base of the PR and between 0621ef6 and 473d29e.

📒 Files selected for processing (3)
  • benchmarks/README.md
  • benchmarks/client-nav/README.md
  • benchmarks/client-nav/package.json
💤 Files with no reviewable changes (1)
  • benchmarks/client-nav/package.json
🚧 Files skipped from review as they are similar to previous changes (1)
  • benchmarks/README.md

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


📝 Walkthrough

Walkthrough

The client-navigation hydration benchmark now covers React and Solid. The change adds SSR fixtures, hydration harnesses, lifecycle tests, and performance targets for both frameworks. It removes Vue hydration from the documentation and package targets. The expected CPU result count per repetition decreases from 135 to 134.

Changes

Client-navigation hydration benchmarks

Layer / File(s) Summary
Benchmark coverage and registration
benchmarks/README.md, benchmarks/client-nav/README.md, benchmarks/client-nav/package.json
The documentation and package targets list React and Solid hydration and omit Vue. The expected CPU result count per repetition is 134.
React fixture and hydration flow
benchmarks/client-nav/scenarios/hydration/react/fixture.ts, benchmarks/client-nav/scenarios/hydration/react/src/*, benchmarks/client-nav/scenarios/hydration/react/generate-fixture.mjs
The React scenario defines routes and fixture data, renders server HTML, generates the hydration fixture, and restores router state before mounting the client.
React benchmark lifecycle and validation
benchmarks/client-nav/scenarios/hydration/react/setup.ts, benchmarks/client-nav/scenarios/hydration/react/settle.ts, benchmarks/client-nav/scenarios/hydration/react/hydration.test.ts, benchmarks/client-nav/scenarios/hydration/react/{project.json,tsconfig.json,vite.config.ts,vite.server.config.ts,speed.bench.ts}
The harness prepares isolated jsdom samples, waits for hydration and scheduler settlement, validates restored state, and defines unit-test and performance targets.
Solid fixture and hydration flow
benchmarks/client-nav/scenarios/hydration/solid/fixture.ts, benchmarks/client-nav/scenarios/hydration/solid/src/*, benchmarks/client-nav/scenarios/hydration/solid/generate-fixture.mjs
The Solid scenario defines routes and fixture data, renders server HTML, generates the hydration fixture, and restores router state before hydrating the DOM.
Solid benchmark lifecycle and validation
benchmarks/client-nav/scenarios/hydration/solid/setup.ts, benchmarks/client-nav/scenarios/hydration/solid/hydration.test.ts, benchmarks/client-nav/scenarios/hydration/solid/{project.json,tsconfig.json,vite.config.ts,vite.server.config.ts,speed.bench.ts}
The harness prepares isolated jsdom samples, waits for hydration to settle, validates route and reactive state, and defines unit-test and performance targets.

Priority: ⬇️ Low

Estimated code review effort: 4 (Complex) | ~60 minutes

Change: Feature

Sequence Diagram(s)

sequenceDiagram
  participant renderFixture
  participant generateFixture
  participant setup
  participant ReactClient
  participant TanStackRouter
  renderFixture->>generateFixture: Return server-rendered HTML
  generateFixture->>setup: Write fixture.json with HTML and scripts
  setup->>ReactClient: Execute bootstrap scripts and start hydration
  ReactClient->>TanStackRouter: Restore router hydration payload
  ReactClient-->>setup: Resolve hydration and expose snapshot
Loading
sequenceDiagram
  participant renderFixture
  participant generateFixture
  participant setup
  participant SolidClient
  participant SolidRouter
  renderFixture->>generateFixture: Return server-rendered HTML
  generateFixture->>setup: Write fixture.json with HTML and scripts
  setup->>SolidClient: Execute bootstrap scripts and start hydration
  SolidClient->>SolidRouter: Restore router hydration state
  SolidClient-->>setup: Expose readiness and snapshot
Loading

Suggested reviewers: schiller-manuel

Merge Risk: ⚪ Minimal · up to 473d2

This adds React and Solid hydration benchmarks and removes Vue from the documented coverage. No concrete workflow or user-facing failure is established; confirm the published CPU-result count separately.

Architecture Summary

Architecture risk: 🔵 Low · up to 473d2

The change affects 1 system.

Changed systems: benchmarks

Architecture concerns
No architecture-level concerns identified.

Review details

Systems and components

  • observed — benchmarks (service) was modified; 27 changed files map to changed impact.

Before / after behavior

  • observed — Modified behavior in benchmarks/client-nav/scenarios/hydration/react/fixture.ts: New fixture file defining link-count and URL constants, a Diagnostics interface with its createDiagnostics initializer factory, and the FixtureArtifact interface for rendered HTML plus scripts.
  • observed — Modified behavior in benchmarks/client-nav/scenarios/hydration/react/generate-fixture.mjs: Added a production-mode fixture generation script that dynamically loads renderFixture, renders HTML, validates inline hydration scripts including $_TSR, writes the HTML and script contents to dist/fixture.json, and closes the JSDOM window in all cases.
  • observed — Modified behavior in benchmarks/client-nav/scenarios/hydration/react/project.json: Adds a new Nx project defining the four targets build:client (production vite build on the server config, fixture generation, then a production vite build on the main config), test:unit (vitest run), test:perf (vitest bench in production mode), and test:types:client (tsc type-check), with build:client and the type-check target depending on the @tanstack/react-router build and both test targets depending on build:client.
  • observed — Modified behavior in benchmarks/client-nav/scenarios/hydration/react/speed.bench.ts: Creates the new React client-hydration benchmark file, registering a client-hydration describe block that runs scenario.before and scenario.after as Vitest hooks and a single bench case that awaits scenario.run() with a 5000 ms time budget, 1000 ms warmup, 20 warmup iterations, scenario.installIterationHooks as the Tinybench setup hook, and throws: true.
🚥 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 57 functions across 31 files. (3 skipped: … Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
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.
Title check ✅ Passed The title clearly and concisely describes the main change: adding React and Solid hydration scenarios to the client-navigation benchmark.
Description check ✅ Passed The description is detailed and covers the changes, motivation, workload, validation, testing, and release impact. It does not reproduce the template's checklist headings or checkbox items, but it pro…
Full details: Docstring Coverage

Explanation

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 57 functions across 31 files. (3 skipped: 3 unsupported.)

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Commit to this branch
  • Create a new PR

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 15, 2026 •

Copy link
Copy Markdown
Contributor

🚀 Changeset Version Preview

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

🟩 Patch bumps

Package Version Reason
@tanstack/react-router 1.170.39 → 1.170.40 Changeset
@tanstack/router-core 1.171.32 → 1.171.33 Changeset
@tanstack/solid-router 1.170.36 → 1.170.37 Changeset
@tanstack/start-client-core 1.170.32 → 1.170.33 Changeset
@tanstack/start-server-core 1.169.37 → 1.169.38 Changeset
@tanstack/vue-router 1.170.35 → 1.170.36 Changeset
@tanstack/react-start 1.168.58 → 1.168.59 Dependent
@tanstack/react-start-client 1.168.37 → 1.168.38 Dependent
@tanstack/react-start-rsc 0.1.57 → 0.1.58 Dependent
@tanstack/react-start-server 1.167.44 → 1.167.45 Dependent
@tanstack/router-cli 1.167.38 → 1.167.39 Dependent
@tanstack/router-generator 1.167.38 → 1.167.39 Dependent
@tanstack/router-plugin 1.168.40 → 1.168.41 Dependent
@tanstack/router-vite-plugin 1.167.40 → 1.167.41 Dependent
@tanstack/solid-start 1.168.55 → 1.168.56 Dependent
@tanstack/solid-start-client 1.168.35 → 1.168.36 Dependent
@tanstack/solid-start-server 1.167.42 → 1.167.43 Dependent
@tanstack/start-plugin-core 1.171.47 → 1.171.48 Dependent
@tanstack/start-static-server-functions 1.167.37 → 1.167.38 Dependent
@tanstack/start-storage-context 1.167.34 → 1.167.35 Dependent
@tanstack/vue-start 1.168.54 → 1.168.55 Dependent
@tanstack/vue-start-client 1.167.38 → 1.167.39 Dependent
@tanstack/vue-start-server 1.167.42 → 1.167.43 Dependent

@github-actions

github-actions Bot commented Sep 15, 2026 •

Copy link
Copy Markdown
Contributor

Bundle Size Benchmarks

This pull request does not affect bundle size in any measured scenario.

@pkg-pr-new

pkg-pr-new Bot commented Sep 15, 2026 •

Copy link
Copy Markdown
More templates

@tanstack/arktype-adapter

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

@tanstack/eslint-plugin-router

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

@tanstack/eslint-plugin-start

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

@tanstack/history

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

@tanstack/nitro-v2-vite-plugin

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

@tanstack/react-router

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

@tanstack/react-router-devtools

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

@tanstack/react-router-ssr-query

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

@tanstack/react-start

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

@tanstack/react-start-client

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

@tanstack/react-start-rsc

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

@tanstack/react-start-server

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

@tanstack/router-cli

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

@tanstack/router-core

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

@tanstack/router-devtools

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

@tanstack/router-devtools-core

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

@tanstack/router-generator

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

@tanstack/router-plugin

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

@tanstack/router-ssr-query-core

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

@tanstack/router-utils

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

@tanstack/router-vite-plugin

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

@tanstack/solid-router

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

@tanstack/solid-router-devtools

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

@tanstack/solid-router-ssr-query

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

@tanstack/solid-start

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

@tanstack/solid-start-client

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

@tanstack/solid-start-server

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

@tanstack/start-client-core

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

@tanstack/start-fn-stubs

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

@tanstack/start-plugin-core

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

@tanstack/start-server-core

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

@tanstack/start-static-server-functions

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

@tanstack/start-storage-context

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

@tanstack/valibot-adapter

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

@tanstack/virtual-file-routes

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

@tanstack/vue-router

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

@tanstack/vue-router-devtools

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

@tanstack/vue-router-ssr-query

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

@tanstack/vue-start

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

@tanstack/vue-start-client

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

@tanstack/vue-start-server

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

@tanstack/zod-adapter

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

commit: 17aef64

@codspeed

codspeed Bot commented Sep 15, 2026 •

Copy link
Copy Markdown

Merging this PR will degrade performance by 3.35%

⚠️ Different runtime environments detected

Some benchmarks with significant performance changes were compared across different runtime environments,
which may affect the accuracy of the results.

Open the report in CodSpeed to investigate

❌ 1 (👁 1) regressed benchmark
✅ 188 untouched benchmarks
🆕 2 new benchmarks
⏩ 3 skipped benchmarks1

Performance Changes

Mode Benchmark BASE HEAD Efficiency
🆕 Simulation hydrate restored route state and mixed Links (solid) N/A 401.2 ms N/A
🆕 Simulation hydrate restored route state and mixed Links (react) N/A 249.2 ms N/A
👁 Memory mem server error-paths unmatched (react) 859.6 KB 889.3 KB -3.35%

Comparing bench/react-client-hydration (17aef64) with main (e81845f)

Open in CodSpeed

Footnotes

  1. 3 benchmarks were skipped, so the baseline results were used instead. If they were deleted from the codebase, click here and archive them to remove them from the performance reports. ↩

@Sheraff Sheraff changed the title bench(client-nav): add React hydration scenario bench(client-nav): add React, Solid, and Vue hydration scenarios Sep 15, 2026
nx-cloud[bot]

This comment was marked as outdated.

nx-cloud[bot]

This comment was marked as outdated.

@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 traced the failing Vue hydration test to a Link active-class mismatch inside @tanstack/vue-router itself, not in any code this PR touches — this PR only adds new benchmark scenario files. The PR description confirms this exact mismatch is a known, pre-existing bug already fixed in a separate PR (#8440) that is intentionally kept out of this one, so we're not proposing a fix here.

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

@TanStack TanStack deleted a comment from codspeed Bot Sep 23, 2026
@Sheraff Sheraff changed the title bench(client-nav): add React, Solid, and Vue hydration scenarios bench(client-nav): add React and Solid hydration scenarios Sep 25, 2026
@Sheraff
Sheraff merged commit bb4423e into main Sep 25, 2026
26 checks passed
@Sheraff
Sheraff deleted the bench/react-client-hydration branch September 25, 2026 18:43
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant