Skip to content

test: add cross-framework client navigation benchmarks#6800

Merged
Sheraff merged 17 commits intomainfrom
opencode/mighty-engine
Mar 2, 2026
Merged

test: add cross-framework client navigation benchmarks#6800
Sheraff merged 17 commits intomainfrom
opencode/mighty-engine

Conversation

@Sheraff
Copy link
Contributor

@Sheraff Sheraff commented Mar 2, 2026

  • new dedicated @benchmarks/client-nav workspace package, w/ React, Solid, and Vue "client navigation" benchmarks

    • locally run everything: pnpm nx run @benchmarks/client-nav:test:perf (or pnpm benchmark:client-nav)
    • locally run only one: pnpm nx run @benchmarks/client-nav:test:perf:solid
    • on CI it runs in the CodSpeed harness to give us a dashboard https://codspeed.io/TanStack/router
  • benchmark details

    • runs on vitest bench
    • executes built code
    • still has a bit of "testing harness" overhead (testing-library, vitest, promises)
    • mounts 20 useParams, 20 useSearch, 20 Link on the __root, and navigate many times the /$id route by changing its params / search
  • moved existing "bundle size" benchmark to the same root /benchmarks folder, and in a later PR will add an SSR setup too

    • now accessible with pnpm nx run @benchmarks/bundle-size:build (or still like before pnpm benchmark:bundle-size)

Warning

I couldn't get the Solid version of this new test to work. We could merge without it and get to it later...

Summary by CodeRabbit

  • New Features

    • Added client-side navigation performance benchmarks for React, Solid, and Vue.
    • Added an npm script to run the client-nav benchmarks.
  • Documentation

    • Added a benchmarking guide for running client-side navigation tests.
  • Chores

    • Integrated benchmarks into the workspace, updated bundle-size wiring and paths, and added a CI workflow to run client-nav benchmarks.

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Mar 2, 2026

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
📝 Walkthrough

Walkthrough

Adds a new cross-framework client-side navigation benchmarking suite under benchmarks/client-nav/ (React, Solid, Vue) with Vitest configs and TS projects, workspace and root script/workflow updates, a new client-nav CI workflow, and relocates/renames bundle-size benchmark artifacts to benchmarks/bundle-size/.

Changes

Cohort / File(s) Summary
Client Navigation Benchmarks - Core Setup
benchmarks/client-nav/README.md, benchmarks/client-nav/package.json, benchmarks/client-nav/vitest.config.ts, benchmarks/client-nav/vitest.setup.ts, benchmarks/client-nav/tsconfig.json
New benchmark package: scripts, dependencies, Nx targets, aggregated Vitest config and test setup (React act env + scrollTo mock).
React Navigation Benchmark
benchmarks/client-nav/react/speed.bench.tsx, benchmarks/client-nav/react/vitest.config.ts, benchmarks/client-nav/react/tsconfig.json
Adds React navigation perf benchmark using TanStack React Router and Vitest config with React plugin and optional CodSpeed instrumentation.
Solid Navigation Benchmark
benchmarks/client-nav/solid/speed.bench.tsx, benchmarks/client-nav/solid/vitest.config.ts, benchmarks/client-nav/solid/tsconfig.json
Adds Solid navigation perf benchmark, Vitest config with vite-plugin-solid and inline deps, plus Solid TS config.
Vue Navigation Benchmark
benchmarks/client-nav/vue/speed.bench.tsx, benchmarks/client-nav/vue/vitest.config.ts, benchmarks/client-nav/vue/tsconfig.json
Adds Vue navigation perf benchmark with router-based stress tests and Vitest config using Vue JSX.
Bundle-Size Migration
benchmarks/bundle-size/package.json, benchmarks/bundle-size/README.md, scripts/benchmarks/bundle-size/measure.mjs
Renames/relocates bundle-size benchmark to benchmarks/bundle-size, updates package name, some dependency versions, and default measure paths.
Workspace & Root Config Updates
pnpm-workspace.yaml, package.json, .github/workflows/bundle-size.yml
Adds benchmarks/* to workspace, removes e2e/bundle-size, exposes benchmark:client-nav script, and updates workflows to reference benchmarks/bundle-size paths/targets.
Client-Nav CI Workflow
.github/workflows/client-nav-benchmarks.yml
New GitHub Actions workflow to run client-nav benchmarks (React, Solid, Vue) via CodSpeed on push/PR/manual dispatch.

Sequence Diagram(s)

sequenceDiagram
    participant CI as CI / GitHub Actions
    participant NX as pnpm / nx
    participant Vitest as Vitest (runner)
    participant App as RouterProvider / App
    participant Router as MemoryHistory Router
    CI->>NX: pnpm nx run `@benchmarks/client-nav`:test:perf
    NX->>Vitest: start project (react / solid / vue)
    Vitest->>App: mount RouterProvider
    App->>Router: createTestRouter (memoryHistory)
    loop navigations
      Vitest->>Router: navigate to /{id}?{q} (replace)
      Router->>App: render updates / onRendered
      App->>Vitest: notify render complete
    end
    Vitest->>CI: emit results / CodSpeed upload
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

Suggested labels

package: react-router, package: solid-router, package: vue-router

Suggested reviewers

  • schiller-manuel
  • nlynzaad

Poem

🐰 I hopped through routers, tails a-fluff and bright,

React, Solid, Vue — I raced them through the night,
Benchmarks lined up, numbers tidy and clear,
Bundle moved snugly to the burrow near,
I twitch my whiskers and cheer with a bite.

🚥 Pre-merge checks | ✅ 2 | ❌ 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%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and specifically describes the main change: adding cross-framework client navigation benchmarks for React, Solid, and Vue, which aligns directly with the changeset.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch opencode/mighty-engine

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

@nx-cloud
Copy link

nx-cloud bot commented Mar 2, 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 835a825

Command Status Duration Result
nx run @benchmarks/client-nav:test:perf:solid ❌ Failed 1m 14s View ↗
nx run @benchmarks/client-nav:test:perf:vue ✅ Succeeded 1m 23s View ↗
nx run @benchmarks/client-nav:test:perf:react ✅ Succeeded 1m 26s View ↗

☁️ Nx Cloud last updated this comment at 2026-03-02 16:51:04 UTC

Copy link

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 86c2386154

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

@github-actions
Copy link

github-actions bot commented Mar 2, 2026

Bundle Size Benchmarks

  • Commit: c40bf25df042
  • Measured at: 2026-03-02T07:58:00.634Z
  • Baseline source: history:545c721c0de5
  • Dashboard: bundle-size history
Scenario Current (gzip) Delta vs baseline Raw Brotli Trend
react-router.minimal 86.58 KiB 0 B (0.00%) 272.45 KiB 75.22 KiB ▁██████████
react-router.full 89.61 KiB 0 B (0.00%) 282.78 KiB 77.90 KiB ▁██████████
solid-router.minimal 35.88 KiB 0 B (0.00%) 107.56 KiB 32.26 KiB ▁██████████
solid-router.full 40.21 KiB 0 B (0.00%) 120.61 KiB 36.13 KiB ▁██████████
vue-router.minimal 51.75 KiB 0 B (0.00%) 147.54 KiB 46.50 KiB ▁██████████
vue-router.full 56.55 KiB 0 B (0.00%) 163.12 KiB 50.86 KiB ▁██████████
react-start.minimal 99.11 KiB 0 B (0.00%) 311.58 KiB 85.68 KiB ▁██████████
react-start.full 102.50 KiB 0 B (0.00%) 321.39 KiB 88.63 KiB ▁▆▆▆▆▆█████
solid-start.minimal 48.19 KiB 0 B (0.00%) 145.13 KiB 42.67 KiB ▁██████████
solid-start.full 53.68 KiB 0 B (0.00%) 161.08 KiB 47.37 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 2, 2026

More templates

@tanstack/arktype-adapter

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

@tanstack/eslint-plugin-router

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

@tanstack/history

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

@tanstack/nitro-v2-vite-plugin

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

@tanstack/react-router

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

@tanstack/react-router-devtools

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

@tanstack/react-router-ssr-query

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

@tanstack/react-start

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

@tanstack/react-start-client

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

@tanstack/react-start-server

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

@tanstack/router-cli

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

@tanstack/router-core

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

@tanstack/router-devtools

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

@tanstack/router-devtools-core

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

@tanstack/router-generator

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

@tanstack/router-plugin

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

@tanstack/router-ssr-query-core

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

@tanstack/router-utils

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

@tanstack/router-vite-plugin

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

@tanstack/solid-router

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

@tanstack/solid-router-devtools

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

@tanstack/solid-router-ssr-query

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

@tanstack/solid-start

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

@tanstack/solid-start-client

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

@tanstack/solid-start-server

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

@tanstack/start-client-core

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

@tanstack/start-fn-stubs

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

@tanstack/start-plugin-core

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

@tanstack/start-server-core

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

@tanstack/start-static-server-functions

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

@tanstack/start-storage-context

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

@tanstack/valibot-adapter

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

@tanstack/virtual-file-routes

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

@tanstack/vue-router

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

@tanstack/vue-router-devtools

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

@tanstack/vue-router-ssr-query

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

@tanstack/vue-start

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

@tanstack/vue-start-client

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

@tanstack/vue-start-server

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

@tanstack/zod-adapter

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

commit: 0b94efe

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 4

🧹 Nitpick comments (2)
benchmarks/client-nav/vitest.setup.ts (1)

3-4: Avoid @ts-expect-error for global setup typing.

At Lines 3–4, declare the global type instead of suppressing errors to maintain strict typing compliance.

♻️ Suggested typed alternative
 import { vi } from 'vitest'
 
-// `@ts-expect-error`
-global.IS_REACT_ACT_ENVIRONMENT = true
+declare global {
+  // eslint-disable-next-line no-var
+  var IS_REACT_ACT_ENVIRONMENT: boolean
+}
+
+globalThis.IS_REACT_ACT_ENVIRONMENT = true
 
 window.scrollTo = vi.fn()

This follows the established pattern in the codebase and aligns with the coding guideline requiring strict TypeScript type safety for **/*.{ts,tsx} files.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@benchmarks/client-nav/vitest.setup.ts` around lines 3 - 4, Replace the //
`@ts-expect-error` hack by adding a proper global type declaration for
IS_REACT_ACT_ENVIRONMENT: declare global { var IS_REACT_ACT_ENVIRONMENT: boolean
} (or property on interface Global if preferred) in this module, ensure the file
is treated as a module by adding export {} if needed, then remove the
`@ts-expect-error` and assign global.IS_REACT_ACT_ENVIRONMENT = true; this keeps
strict typing while preserving the existing runtime assignment.
benchmarks/client-nav/react/speed.bench.tsx (1)

85-85: Prefer a non-rejecting default for next.

Using Promise.reject() here can produce noisy unhandled rejections if the callback is touched before setup reassigns it. A resolved no-op default is safer for harness stability.

♻️ Proposed tweak
-  let next: () => Promise<void> = () => Promise.reject()
+  let next: () => Promise<void> = async () => {}
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@benchmarks/client-nav/react/speed.bench.tsx` at line 85, The default `next`
callback is initialized to a rejecting promise which can trigger unhandled
rejections; change the initializer for the `next` variable (declared as `let
next: () => Promise<void>`) to a non-rejecting no-op (e.g., a resolved promise
or an async no-op) so callers touching `next` before `setup` runs won't cause
runtime unhandled rejection noise.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@benchmarks/client-nav/solid/speed.bench.tsx`:
- Line 77: Remove the unpaired console.time('render') call in the route
component (it currently has no matching console.timeEnd('render')), so delete
that console.time('render') statement from the component to avoid adding extra
overhead to the navigation benchmark; if timing was intended instead, add a
matching console.timeEnd('render') at the end of the component render logic, but
otherwise simply remove the console.time('render') line.

In `@benchmarks/client-nav/vue/speed.bench.tsx`:
- Around line 114-120: The benchmark currently uses a numeric nextId when
calling navigate, causing Vue to pass numbers into params and search; change the
navigate call in speed.bench.tsx to pass string IDs by converting nextId to a
string (e.g., use nextId.toString() or template `${nextId}`) for both params and
search so route params/search are normalized to strings; locate the usage around
the nextId variable and the navigate({ to: '/$id', params: { id: ... }, search:
{ id: ... }, replace: true }) call and update both places to use the stringified
id.
- Line 75: Remove the unnecessary type cast on the route definition by replacing
the "component: Root as any" usage with "component: Root" so the route's
component property uses its existing unknown-compatible type instead of
bypassing type safety; update the route object where the component field is set
(look for the "component" property assigned from the Root identifier in
speed.bench.tsx) and remove the "as any" cast to comply with TypeScript strict
mode.

In `@e2e/bundle-size/package.json`:
- Around line 24-27: The package.json lists an incompatible pair:
"@vitejs/plugin-vue" at 5.2.3 and "vite" at ^7.3.1; update either dependency so
they match supported peer ranges — either upgrade "@vitejs/plugin-vue" to a
version that declares support for Vite 7 (replace 5.2.3 with the plugin's
Vite-7-compatible release) or downgrade "vite" to a 6.x range (e.g., ^6.x) so it
satisfies "@vitejs/plugin-vue@5.2.3"; ensure any related plugins like
"@vitejs/plugin-vue-jsx" are also bumped/downgraded to compatible versions and
run install to verify peer deps resolve.

---

Nitpick comments:
In `@benchmarks/client-nav/react/speed.bench.tsx`:
- Line 85: The default `next` callback is initialized to a rejecting promise
which can trigger unhandled rejections; change the initializer for the `next`
variable (declared as `let next: () => Promise<void>`) to a non-rejecting no-op
(e.g., a resolved promise or an async no-op) so callers touching `next` before
`setup` runs won't cause runtime unhandled rejection noise.

In `@benchmarks/client-nav/vitest.setup.ts`:
- Around line 3-4: Replace the // `@ts-expect-error` hack by adding a proper
global type declaration for IS_REACT_ACT_ENVIRONMENT: declare global { var
IS_REACT_ACT_ENVIRONMENT: boolean } (or property on interface Global if
preferred) in this module, ensure the file is treated as a module by adding
export {} if needed, then remove the `@ts-expect-error` and assign
global.IS_REACT_ACT_ENVIRONMENT = true; this keeps strict typing while
preserving the existing runtime assignment.

ℹ️ Review info

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between c40bf25 and 53b2ec5.

⛔ Files ignored due to path filters (1)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (17)
  • benchmarks/client-nav/README.md
  • benchmarks/client-nav/package.json
  • benchmarks/client-nav/react/speed.bench.tsx
  • benchmarks/client-nav/react/tsconfig.json
  • benchmarks/client-nav/react/vitest.config.ts
  • benchmarks/client-nav/solid/speed.bench.tsx
  • benchmarks/client-nav/solid/tsconfig.json
  • benchmarks/client-nav/solid/vitest.config.ts
  • benchmarks/client-nav/tsconfig.json
  • benchmarks/client-nav/vitest.config.ts
  • benchmarks/client-nav/vitest.setup.ts
  • benchmarks/client-nav/vue/speed.bench.tsx
  • benchmarks/client-nav/vue/tsconfig.json
  • benchmarks/client-nav/vue/vitest.config.ts
  • e2e/bundle-size/package.json
  • package.json
  • pnpm-workspace.yaml

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 4

♻️ Duplicate comments (3)
benchmarks/client-nav/vue/speed.bench.tsx (1)

93-93: 🛠️ Refactor suggestion | 🟠 Major

Drop as any on the root route component.
Please avoid bypassing types here; use component: Root directly.

Suggested fix
-    component: Root as any,
+    component: Root,

As per coding guidelines: **/*.{ts,tsx}: Use TypeScript strict mode with extensive type safety.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@benchmarks/client-nav/vue/speed.bench.tsx` at line 93, The route entry
currently casts the Root component via "component: Root as any" which bypasses
type safety; change it to "component: Root" and update the route typing or the
Root export so they match (e.g., ensure Root is typed as a Vue component or the
route config uses the correct generic/RouteRecordRaw-compatible type). Locate
the route object where "component: Root as any" appears, remove the "as any"
cast, and if TypeScript errors appear, fix the Root export signature or adjust
the route type declaration so Root's actual type is accepted without casting.
benchmarks/bundle-size/package.json (1)

24-27: ⚠️ Potential issue | 🟠 Major

Resolve the Vue plugin/Vite version mismatch.
@vitejs/plugin-vue@^5.2.3 is typically paired with Vite 5/6, while this package pins vite@^7.3.1. Please align these versions to avoid peer-resolution/build issues.

What is the peer dependency range for vite in `@vitejs/plugin-vue`@5.2.3 and `@vitejs/plugin-vue-jsx`@4.1.2?
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@benchmarks/bundle-size/package.json` around lines 24 - 27, package.json
currently mixes "@vitejs/plugin-vue" and "@vitejs/plugin-vue-jsx" versions that
target an older Vite with vite@^7.3.1, causing a peer-dependency mismatch; check
the peer dependency ranges for `@vitejs/plugin-vue`@5.2.3 and
`@vitejs/plugin-vue-jsx`@4.1.2 (via npm info or the registry) and then either (A)
upgrade the two plugins to releases whose peerDependencies include vite@^7
(update "@vitejs/plugin-vue" and "@vitejs/plugin-vue-jsx" entries) or (B)
downgrade the "vite" version to the range required by the plugin versions; after
updating package.json run install and verify with npm ls/pnpm ls to ensure no
peer conflicts remain.
benchmarks/client-nav/solid/speed.bench.tsx (1)

88-90: ⚠️ Potential issue | 🟠 Major

Remove unpaired console.time('render') from benchmark path.

console.time('render') at Line 89 has no matching console.timeEnd, which adds non-target overhead/noise to navigation measurements.

Suggested fix
     component: () => {
-      console.time('render')
       return <div />
     },
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@benchmarks/client-nav/solid/speed.bench.tsx` around lines 88 - 90, The
benchmark's component function contains an unpaired console.time('render') call
(in the component returned by component: () => { ... }) which skews navigation
measurements; remove the standalone console.time('render') from the component
(or if measuring, add a matching console.timeEnd('render') in the corresponding
lifecycle/after-render hook) so that console.time('render') is either fully
paired with console.timeEnd('render') or omitted entirely from the component
render path.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@benchmarks/client-nav/package.json`:
- Around line 31-35: Update the `@vitejs/plugin-vue` dependency in package.json
from "^5.2.3" to a 6.x release (e.g. "^6.0.0") so it is compatible with
vite@^7.3.1; adjust the "@vitejs/plugin-vue" entry in package.json, then
reinstall dependencies (npm/yarn/pnpm install) and regenerate the lockfile to
resolve the peer dependency conflict; verify project builds using the updated
`@vitejs/plugin-vue` version.

In `@benchmarks/client-nav/react/speed.bench.tsx`:
- Line 4: The import rootRouteId is unused and causing lint failures; remove
rootRouteId from the import statement (the import line that currently imports
rootRouteId from '@tanstack/router-core') or replace it by using the identifier
where needed; specifically delete rootRouteId from the import so only actually
used exports remain.

In `@benchmarks/client-nav/solid/speed.bench.tsx`:
- Around line 67-75: Replace the three uses of selectors.map(...) rendering
Params, Search, and Links with Solid's <For> control-flow to comply with Solid
best practices: import For from 'solid-js' (or use the existing import) and
change each block to <For each={selectors}>{() => <Params />}</For>, similarly
for Search and Links, ensuring you pass the items via the each prop (and use the
item/index callback if you need unique keys or item data) instead of using
.map().

In `@benchmarks/client-nav/vue/speed.bench.tsx`:
- Line 4: The file imports rootRouteId which is unused; remove the unused import
by deleting the import specifier rootRouteId from the import statement (the
import line "import { rootRouteId } from '@tanstack/router-core'") or remove the
entire import if nothing else is imported, ensuring no other references to
rootRouteId remain in the file.

---

Duplicate comments:
In `@benchmarks/bundle-size/package.json`:
- Around line 24-27: package.json currently mixes "@vitejs/plugin-vue" and
"@vitejs/plugin-vue-jsx" versions that target an older Vite with vite@^7.3.1,
causing a peer-dependency mismatch; check the peer dependency ranges for
`@vitejs/plugin-vue`@5.2.3 and `@vitejs/plugin-vue-jsx`@4.1.2 (via npm info or the
registry) and then either (A) upgrade the two plugins to releases whose
peerDependencies include vite@^7 (update "@vitejs/plugin-vue" and
"@vitejs/plugin-vue-jsx" entries) or (B) downgrade the "vite" version to the
range required by the plugin versions; after updating package.json run install
and verify with npm ls/pnpm ls to ensure no peer conflicts remain.

In `@benchmarks/client-nav/solid/speed.bench.tsx`:
- Around line 88-90: The benchmark's component function contains an unpaired
console.time('render') call (in the component returned by component: () => { ...
}) which skews navigation measurements; remove the standalone
console.time('render') from the component (or if measuring, add a matching
console.timeEnd('render') in the corresponding lifecycle/after-render hook) so
that console.time('render') is either fully paired with
console.timeEnd('render') or omitted entirely from the component render path.

In `@benchmarks/client-nav/vue/speed.bench.tsx`:
- Line 93: The route entry currently casts the Root component via "component:
Root as any" which bypasses type safety; change it to "component: Root" and
update the route typing or the Root export so they match (e.g., ensure Root is
typed as a Vue component or the route config uses the correct
generic/RouteRecordRaw-compatible type). Locate the route object where
"component: Root as any" appears, remove the "as any" cast, and if TypeScript
errors appear, fix the Root export signature or adjust the route type
declaration so Root's actual type is accepted without casting.

ℹ️ Review info

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 53b2ec5 and 80d48b5.

⛔ Files ignored due to path filters (1)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (63)
  • .github/workflows/bundle-size.yml
  • .github/workflows/client-nav-benchmarks.yml
  • benchmarks/bundle-size/.gitignore
  • benchmarks/bundle-size/README.md
  • benchmarks/bundle-size/package.json
  • benchmarks/bundle-size/results/.gitkeep
  • benchmarks/bundle-size/scenarios/react-router-full/index.html
  • benchmarks/bundle-size/scenarios/react-router-full/src/main.tsx
  • benchmarks/bundle-size/scenarios/react-router-full/src/routes/__root.tsx
  • benchmarks/bundle-size/scenarios/react-router-full/src/routes/index.tsx
  • benchmarks/bundle-size/scenarios/react-router-full/vite.config.ts
  • benchmarks/bundle-size/scenarios/react-router-minimal/index.html
  • benchmarks/bundle-size/scenarios/react-router-minimal/src/main.tsx
  • benchmarks/bundle-size/scenarios/react-router-minimal/src/routes/__root.tsx
  • benchmarks/bundle-size/scenarios/react-router-minimal/src/routes/index.tsx
  • benchmarks/bundle-size/scenarios/react-router-minimal/vite.config.ts
  • benchmarks/bundle-size/scenarios/react-start-full/src/router.tsx
  • benchmarks/bundle-size/scenarios/react-start-full/src/routes/__root.tsx
  • benchmarks/bundle-size/scenarios/react-start-full/src/routes/index.tsx
  • benchmarks/bundle-size/scenarios/react-start-full/vite.config.ts
  • benchmarks/bundle-size/scenarios/react-start-minimal/src/router.tsx
  • benchmarks/bundle-size/scenarios/react-start-minimal/src/routes/__root.tsx
  • benchmarks/bundle-size/scenarios/react-start-minimal/src/routes/index.tsx
  • benchmarks/bundle-size/scenarios/react-start-minimal/vite.config.ts
  • benchmarks/bundle-size/scenarios/solid-router-full/index.html
  • benchmarks/bundle-size/scenarios/solid-router-full/src/main.tsx
  • benchmarks/bundle-size/scenarios/solid-router-full/src/routes/__root.tsx
  • benchmarks/bundle-size/scenarios/solid-router-full/src/routes/index.tsx
  • benchmarks/bundle-size/scenarios/solid-router-full/vite.config.ts
  • benchmarks/bundle-size/scenarios/solid-router-minimal/index.html
  • benchmarks/bundle-size/scenarios/solid-router-minimal/src/main.tsx
  • benchmarks/bundle-size/scenarios/solid-router-minimal/src/routes/__root.tsx
  • benchmarks/bundle-size/scenarios/solid-router-minimal/src/routes/index.tsx
  • benchmarks/bundle-size/scenarios/solid-router-minimal/vite.config.ts
  • benchmarks/bundle-size/scenarios/solid-start-full/src/router.tsx
  • benchmarks/bundle-size/scenarios/solid-start-full/src/routes/__root.tsx
  • benchmarks/bundle-size/scenarios/solid-start-full/src/routes/index.tsx
  • benchmarks/bundle-size/scenarios/solid-start-full/vite.config.ts
  • benchmarks/bundle-size/scenarios/solid-start-minimal/src/router.tsx
  • benchmarks/bundle-size/scenarios/solid-start-minimal/src/routes/__root.tsx
  • benchmarks/bundle-size/scenarios/solid-start-minimal/src/routes/index.tsx
  • benchmarks/bundle-size/scenarios/solid-start-minimal/vite.config.ts
  • benchmarks/bundle-size/scenarios/vue-router-full/index.html
  • benchmarks/bundle-size/scenarios/vue-router-full/src/main.tsx
  • benchmarks/bundle-size/scenarios/vue-router-full/src/routes/__root.tsx
  • benchmarks/bundle-size/scenarios/vue-router-full/src/routes/index.tsx
  • benchmarks/bundle-size/scenarios/vue-router-full/vite.config.ts
  • benchmarks/bundle-size/scenarios/vue-router-minimal/index.html
  • benchmarks/bundle-size/scenarios/vue-router-minimal/src/main.tsx
  • benchmarks/bundle-size/scenarios/vue-router-minimal/src/routes/__root.tsx
  • benchmarks/bundle-size/scenarios/vue-router-minimal/src/routes/index.tsx
  • benchmarks/bundle-size/scenarios/vue-router-minimal/vite.config.ts
  • benchmarks/bundle-size/tsconfig.json
  • benchmarks/client-nav/package.json
  • benchmarks/client-nav/react/speed.bench.tsx
  • benchmarks/client-nav/react/vitest.config.ts
  • benchmarks/client-nav/solid/speed.bench.tsx
  • benchmarks/client-nav/solid/vitest.config.ts
  • benchmarks/client-nav/vue/speed.bench.tsx
  • benchmarks/client-nav/vue/vitest.config.ts
  • package.json
  • pnpm-workspace.yaml
  • scripts/benchmarks/bundle-size/measure.mjs
🚧 Files skipped from review as they are similar to previous changes (3)
  • package.json
  • benchmarks/client-nav/react/vitest.config.ts
  • pnpm-workspace.yaml

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🧹 Nitpick comments (1)
benchmarks/client-nav/react/speed.bench.tsx (1)

109-116: Normalize nextId to string for cross-framework comparability.

Line 110 uses numeric IDs, while the Solid benchmark uses string IDs. Normalizing this removes inconsistent coercion cost from framework comparisons.

🔧 Suggested fix
-      const nextId = id++
+      const nextId = String(id++)
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@benchmarks/client-nav/react/speed.bench.tsx` around lines 109 - 116, The
benchmark's next function uses a numeric nextId which differs from Solid's
string IDs; change the construction of nextId inside next (where id is
incremented) to normalize it to a string (e.g., use String(id++) or
id.toString()) and ensure the same string-valued nextId is passed into
navigate's params and search in the next function so both params and search use
string IDs for consistent cross-framework comparison.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@benchmarks/client-nav/react/speed.bench.tsx`:
- Around line 129-137: The suite currently registers lifecycle twice: remove
per-benchmark lifecycle from the bench options so setup/teardown run only once
via the suite-level beforeAll and afterAll; specifically, keep beforeAll(setup)
and afterAll(teardown) as-is and delete the setup and teardown properties from
the bench('navigate', () => act(next), { ... }) options (which reference setup
and teardown), leaving warmupIterations, time, and the benchmark callback
(act(next)) intact to avoid repeated expensive mounts.

In `@benchmarks/client-nav/vue/speed.bench.tsx`:
- Around line 143-151: The bench call is passing setup/teardown in its options
while the suite already runs beforeAll(setup) and afterAll(teardown), causing
setup to run per iteration; remove setup and teardown from the bench options in
the bench('navigate', () => next(), {...}) invocation so only warmupIterations
and time (and any other per-benchmark settings) remain, leaving beforeAll(setup)
and afterAll(teardown) to handle one-time initialization/cleanup for the suite
and keeping the next() benchmark body unchanged.

---

Nitpick comments:
In `@benchmarks/client-nav/react/speed.bench.tsx`:
- Around line 109-116: The benchmark's next function uses a numeric nextId which
differs from Solid's string IDs; change the construction of nextId inside next
(where id is incremented) to normalize it to a string (e.g., use String(id++) or
id.toString()) and ensure the same string-valued nextId is passed into
navigate's params and search in the next function so both params and search use
string IDs for consistent cross-framework comparison.

ℹ️ Review info

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 80d48b5 and 2c77919.

📒 Files selected for processing (7)
  • .github/workflows/client-nav-benchmarks.yml
  • benchmarks/client-nav/react/speed.bench.tsx
  • benchmarks/client-nav/react/vitest.config.ts
  • benchmarks/client-nav/solid/speed.bench.tsx
  • benchmarks/client-nav/solid/vitest.config.ts
  • benchmarks/client-nav/vue/speed.bench.tsx
  • benchmarks/client-nav/vue/vitest.config.ts
🚧 Files skipped from review as they are similar to previous changes (2)
  • benchmarks/client-nav/solid/vitest.config.ts
  • .github/workflows/client-nav-benchmarks.yml

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

♻️ Duplicate comments (2)
benchmarks/client-nav/vue/speed.bench.tsx (1)

143-151: ⚠️ Potential issue | 🟠 Major

Remove duplicated benchmark lifecycle wiring.

Line 143 and Line 144 already handle one-time suite lifecycle. Re-registering setup/teardown in Line 149 and Line 150 runs mount/subscription work per benchmark cycle, which skews the navigation benchmark.

Suggested fix
   bench('navigate', () => next(), {
     warmupIterations: 1000,
     time: 10_000,
-    setup,
-    teardown,
   })
For Vitest v4, does `bench(name, fn, { setup, teardown })` run `setup`/`teardown` for each benchmark cycle, while `beforeAll`/`afterAll` run once per suite?
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@benchmarks/client-nav/vue/speed.bench.tsx` around lines 143 - 151, The test
registers suite-level lifecycle twice: beforeAll(setup)/afterAll(teardown) and
again in bench('navigate', ..., { setup, teardown }); remove the per-benchmark
setup/teardown from the bench call so the bench uses the suite-level
beforeAll/afterAll; locate the bench invocation named "navigate" and delete the
setup and teardown properties from its options (or alternatively replace
suite-level beforeAll/afterAll with beforeEach/afterEach if you actually want
per-iteration mounting, but do not keep both).
benchmarks/client-nav/react/speed.bench.tsx (1)

129-137: ⚠️ Potential issue | 🟠 Major

Drop per-benchmark setup/teardown to avoid measurement skew.

Line 129 and Line 130 already run suite lifecycle once. Keeping setup/teardown in Line 135 and Line 136 makes render/cleanup execute every cycle and distorts the benchmark.

Suggested fix
   bench('navigate', () => act(next), {
     warmupIterations: 1000,
     time: 10_000,
-    setup,
-    teardown,
   })
In Vitest 4, are `setup` and `teardown` passed to `bench()` executed per benchmark cycle (not once per suite)?
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@benchmarks/client-nav/react/speed.bench.tsx` around lines 129 - 137, The
per-benchmark options currently pass setup and teardown into bench(...) which
causes setup/teardown to run every iteration and skew results; remove setup and
teardown from the bench call (leave beforeAll(setup) and afterAll(teardown) as
the suite lifecycle) so bench('navigate', () => act(next), { warmupIterations:
1000, time: 10_000 }) runs without per-cycle render/cleanup and preserves
accurate timing for the navigate benchmark.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@benchmarks/client-nav/react/speed.bench.tsx`:
- Line 3: The import members from 'vitest' are not alphabetically sorted; update
the import that currently lists bench, describe, beforeAll, afterAll to an
alphabetically ordered list (afterAll, beforeAll, bench, describe) so the
symbols (afterAll, beforeAll, bench, describe) are sorted to satisfy the
sort-imports lint rule.

In `@benchmarks/client-nav/vue/speed.bench.tsx`:
- Line 2: The named imports from vitest are not alphabetically sorted causing
the `sort-imports` lint error; reorder the import specifiers in the import
statement so the members are alphabetized (e.g., afterAll, beforeAll, bench,
describe) to satisfy the linter and keep the import as import { afterAll,
beforeAll, bench, describe } from 'vitest'.

---

Duplicate comments:
In `@benchmarks/client-nav/react/speed.bench.tsx`:
- Around line 129-137: The per-benchmark options currently pass setup and
teardown into bench(...) which causes setup/teardown to run every iteration and
skew results; remove setup and teardown from the bench call (leave
beforeAll(setup) and afterAll(teardown) as the suite lifecycle) so
bench('navigate', () => act(next), { warmupIterations: 1000, time: 10_000 })
runs without per-cycle render/cleanup and preserves accurate timing for the
navigate benchmark.

In `@benchmarks/client-nav/vue/speed.bench.tsx`:
- Around line 143-151: The test registers suite-level lifecycle twice:
beforeAll(setup)/afterAll(teardown) and again in bench('navigate', ..., { setup,
teardown }); remove the per-benchmark setup/teardown from the bench call so the
bench uses the suite-level beforeAll/afterAll; locate the bench invocation named
"navigate" and delete the setup and teardown properties from its options (or
alternatively replace suite-level beforeAll/afterAll with beforeEach/afterEach
if you actually want per-iteration mounting, but do not keep both).

ℹ️ Review info

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 2c77919 and 9e271e3.

📒 Files selected for processing (2)
  • benchmarks/client-nav/react/speed.bench.tsx
  • benchmarks/client-nav/vue/speed.bench.tsx

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

♻️ Duplicate comments (2)
benchmarks/client-nav/vue/speed.bench.tsx (1)

2-2: ⚠️ Potential issue | 🟡 Minor

Sort vitest named imports to keep lint green.

Line 2 still violates sort-imports.

Suggested fix
-import { bench, describe, beforeAll, afterAll } from 'vitest'
+import { afterAll, beforeAll, bench, describe } from 'vitest'
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@benchmarks/client-nav/vue/speed.bench.tsx` at line 2, The named imports from
'vitest' in the import statement (bench, describe, beforeAll, afterAll) are not
sorted and trigger the sort-imports lint rule; reorder them alphabetically
(afterAll, beforeAll, bench, describe) in the import declaration so the import
line for 'vitest' is sorted and the lint error is resolved.
benchmarks/client-nav/react/speed.bench.tsx (1)

3-3: ⚠️ Potential issue | 🟡 Minor

Sort vitest named imports to satisfy lint.

Line 3 still violates sort-imports.

Suggested fix
-import { bench, describe, beforeAll, afterAll } from 'vitest'
+import { afterAll, beforeAll, bench, describe } from 'vitest'
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@benchmarks/client-nav/react/speed.bench.tsx` at line 3, The named imports
from vitest are not sorted; reorder the import specifiers for bench, describe,
beforeAll, and afterAll into alphabetical order (afterAll, beforeAll, bench,
describe) so the import line for vitest satisfies the sort-imports lint rule.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@benchmarks/client-nav/vue/speed.bench.tsx`:
- Around line 30-49: The linter is flagging valid Vue composable usage inside
the setup functions as hook-rule false positives; update the implementations of
Params and Search (the Vue.defineComponent calls with setup using useParams and
useSearch and their select callbacks) to satisfy the hook rule by ensuring the
calls to useParams and useSearch occur unconditionally at the top of the setup
function body (i.e., do not wrap them in conditional logic and avoid late
returns) and keep the select callbacks as pure functions; specifically modify
the setup blocks for Params and Search so useParams(...) and useSearch(...) are
the first statements in setup (refer to the Params and Search component
definitions and the useParams/useSearch usages) to prevent the lint rule from
reporting false positives.

---

Duplicate comments:
In `@benchmarks/client-nav/react/speed.bench.tsx`:
- Line 3: The named imports from vitest are not sorted; reorder the import
specifiers for bench, describe, beforeAll, and afterAll into alphabetical order
(afterAll, beforeAll, bench, describe) so the import line for vitest satisfies
the sort-imports lint rule.

In `@benchmarks/client-nav/vue/speed.bench.tsx`:
- Line 2: The named imports from 'vitest' in the import statement (bench,
describe, beforeAll, afterAll) are not sorted and trigger the sort-imports lint
rule; reorder them alphabetically (afterAll, beforeAll, bench, describe) in the
import declaration so the import line for 'vitest' is sorted and the lint error
is resolved.

ℹ️ Review info

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 9e271e3 and 17c6e64.

📒 Files selected for processing (2)
  • benchmarks/client-nav/react/speed.bench.tsx
  • benchmarks/client-nav/vue/speed.bench.tsx

@Sheraff Sheraff marked this pull request as draft March 2, 2026 14:24
@codspeed-hq
Copy link

codspeed-hq bot commented Mar 2, 2026

Congrats! CodSpeed is installed 🎉

🆕 2 new benchmarks were detected.

You will start to see performance impacts in the reports once the benchmarks are run from your default branch.

Detected benchmarks


Open in CodSpeed

@Sheraff Sheraff marked this pull request as ready for review March 2, 2026 16:31
Copy link

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 9aa595dba3

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

@Sheraff Sheraff marked this pull request as draft March 2, 2026 17:40
@Sheraff Sheraff marked this pull request as ready for review March 2, 2026 17:40
@Sheraff Sheraff requested a review from schiller-manuel March 2, 2026 17:40
Copy link

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 835a825c70

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

@Sheraff Sheraff merged commit 1acc8ea into main Mar 2, 2026
9 of 10 checks passed
@Sheraff Sheraff deleted the opencode/mighty-engine branch March 2, 2026 20:23
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