Skip to content

refactor(router-plugin): Build-time route matching #4714

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 54 commits into
base: main
Choose a base branch
from

Conversation

Sheraff
Copy link
Contributor

@Sheraff Sheraff commented Jul 19, 2025

Performance of matchByPath (router-core > path) can be improved by generating a "pre-compiled" route matching function at build-time

Copy link

nx-cloud bot commented Jul 19, 2025

View your CI Pipeline Execution ↗ for commit 0356bc7

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

☁️ Nx Cloud last updated this comment at 2025-07-27 20:27:52 UTC

Copy link

pkg-pr-new bot commented Jul 19, 2025

More templates

@tanstack/arktype-adapter

npm i https://pkg.pr.new/TanStack/router/@tanstack/arktype-adapter@4714

@tanstack/directive-functions-plugin

npm i https://pkg.pr.new/TanStack/router/@tanstack/directive-functions-plugin@4714

@tanstack/eslint-plugin-router

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

@tanstack/history

npm i https://pkg.pr.new/TanStack/router/@tanstack/history@4714

@tanstack/react-router

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

@tanstack/react-router-devtools

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

@tanstack/react-router-with-query

npm i https://pkg.pr.new/TanStack/router/@tanstack/react-router-with-query@4714

@tanstack/react-start

npm i https://pkg.pr.new/TanStack/router/@tanstack/react-start@4714

@tanstack/react-start-client

npm i https://pkg.pr.new/TanStack/router/@tanstack/react-start-client@4714

@tanstack/react-start-plugin

npm i https://pkg.pr.new/TanStack/router/@tanstack/react-start-plugin@4714

@tanstack/react-start-server

npm i https://pkg.pr.new/TanStack/router/@tanstack/react-start-server@4714

@tanstack/router-cli

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

@tanstack/router-core

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

@tanstack/router-devtools

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

@tanstack/router-devtools-core

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

@tanstack/router-generator

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

@tanstack/router-plugin

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

@tanstack/router-utils

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

@tanstack/router-vite-plugin

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

@tanstack/server-functions-plugin

npm i https://pkg.pr.new/TanStack/router/@tanstack/server-functions-plugin@4714

@tanstack/solid-router

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

@tanstack/solid-router-devtools

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

@tanstack/solid-start

npm i https://pkg.pr.new/TanStack/router/@tanstack/solid-start@4714

@tanstack/solid-start-client

npm i https://pkg.pr.new/TanStack/router/@tanstack/solid-start-client@4714

@tanstack/solid-start-plugin

npm i https://pkg.pr.new/TanStack/router/@tanstack/solid-start-plugin@4714

@tanstack/solid-start-server

npm i https://pkg.pr.new/TanStack/router/@tanstack/solid-start-server@4714

@tanstack/start-client-core

npm i https://pkg.pr.new/TanStack/router/@tanstack/start-client-core@4714

@tanstack/start-plugin-core

npm i https://pkg.pr.new/TanStack/router/@tanstack/start-plugin-core@4714

@tanstack/start-server-core

npm i https://pkg.pr.new/TanStack/router/@tanstack/start-server-core@4714

@tanstack/start-server-functions-client

npm i https://pkg.pr.new/TanStack/router/@tanstack/start-server-functions-client@4714

@tanstack/start-server-functions-fetcher

npm i https://pkg.pr.new/TanStack/router/@tanstack/start-server-functions-fetcher@4714

@tanstack/start-server-functions-server

npm i https://pkg.pr.new/TanStack/router/@tanstack/start-server-functions-server@4714

@tanstack/start-storage-context

npm i https://pkg.pr.new/TanStack/router/@tanstack/start-storage-context@4714

@tanstack/valibot-adapter

npm i https://pkg.pr.new/TanStack/router/@tanstack/valibot-adapter@4714

@tanstack/virtual-file-routes

npm i https://pkg.pr.new/TanStack/router/@tanstack/virtual-file-routes@4714

@tanstack/zod-adapter

npm i https://pkg.pr.new/TanStack/router/@tanstack/zod-adapter@4714

commit: 0356bc7

@Sheraff Sheraff changed the title feat(router-plugin) Build-time route matching refactor(router-plugin): Build-time route matching Jul 19, 2025
@Sheraff Sheraff force-pushed the router-core-build-time-route-matcher branch from fe2e83e to 6e9c361 Compare July 19, 2025 22:05
@Sheraff Sheraff force-pushed the router-core-build-time-route-matcher branch from e0fb7e3 to 7d2b299 Compare July 20, 2025 09:05
@Sheraff Sheraff force-pushed the router-core-build-time-route-matcher branch from 97d0fde to 31700cb Compare July 20, 2025 09:20
Sheraff added a commit that referenced this pull request Jul 23, 2025
We noticed that `parsePathname` is a performance bottleneck during
navigation events. Here's a flamegraph from an application w/ ~300
routes around a navigation event:

<img width="853" height="372" alt="Screenshot 2025-07-22 at 19 36 24"
src="https://github.com/user-attachments/assets/7ed2e09a-8ea9-4170-862a-2d53c3eb4793"
/>


This PR proposes a basic least-recently-used cache implementation (that
data structure is about 4-5x slower than a `Map` according to
benchmarks, and it uses a little more memory).

We can add caching to `parsePathname` now that what it returns is
readonly (#4705), which should
improve the performance of this bottleneck.

The cache is set to a size of 1000. When / if we end up making a
pre-built matcher (WIP #4714), we
maybe can reduce this size. But `parsePathname` is still called w/ built
pathnames so we probably shouldn't remove the cache entirely.


When benchmarking `matchPathname` with and without the cache, we notice
a ~9x increase in throughput with the cache.
```
 ✓  @tanstack/router-core  tests/cache.bench.ts > cache.bench 7191ms
     name             hz     min     max    mean     p75     p99    p995    p999     rme  samples
   · original   1,795.61  0.5055  0.7022  0.5569  0.5604  0.6234  0.6464  0.7022  ±0.22%      898
   · cached    16,307.87  0.0562  0.2294  0.0613  0.0608  0.0767  0.1007  0.1152  ±0.17%     8154   fastest

 BENCH  Summary

   @tanstack/router-core  cached - tests/cache.bench.ts > cache.bench
    9.08x faster than original
```
Assuming this 9x increase translates to a proportional reduction of the
self-time seen in the flamegraph, it would go from 55ms to 6ms.
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