Skip to content

refactor(router-core): improve parseSegment performance, parse without regex - #6470

Merged
Sheraff merged 2 commits into
mainfrom
refactor-router-core-parse-segments-perf-no-regex
Jan 23, 2026
Merged

refactor(router-core): improve parseSegment performance, parse without regex#6470
Sheraff merged 2 commits into
mainfrom
refactor-router-core-parse-segments-perf-no-regex

Conversation

@Sheraff

@SheraffSheraff commented Jan 23, 2026

Copy link
Copy Markdown
Collaborator

parseSegment is in the hot path both for

  • building the initial tree when starting the app
  • every call to interpolatePath, i.e. every Link, every navigation, every preload, ...

Without the comments, this PR adds 7 lines of code in total, but increases performance by 0% to 40% depending on the type of segment we're parsing.

Because there is no enforcement of parameter name syntax at runtime anymore, we introduce

bench

@tanstack/router-core new (character-based) - Static Paths (fast path) - simple static
1.06x faster than old (regex-based)
@tanstack/router-core new (character-based) - Static Paths (fast path) - deep static
1.12x faster than old (regex-based)
@tanstack/router-core new (character-based) - Simple Param Paths ($param) - simple param
1.06x faster than old (regex-based)
@tanstack/router-core new (character-based) - Simple Param Paths ($param) - multiple params
1.12x faster than old (regex-based)
@tanstack/router-core new (character-based) - Curly Brace Params ({$param}) - curly param
1.26x faster than old (regex-based)
@tanstack/router-core new (character-based) - Curly Brace Params ({$param}) - curly with prefix
1.34x faster than old (regex-based)
@tanstack/router-core new (character-based) - Curly Brace Params ({$param}) - curly with prefix+suffix
1.37x faster than old (regex-based)
@tanstack/router-core new (character-based) - Optional Params ({-$param}) - optional param
1.23x faster than old (regex-based)
@tanstack/router-core new (character-based) - Optional Params ({-$param}) - optional with prefix
1.24x faster than old (regex-based)
@tanstack/router-core new (character-based) - Optional Params ({-$param}) - optional with prefix+suffix
1.27x faster than old (regex-based)
@tanstack/router-core new (character-based) - Wildcard Paths ($) - simple wildcard
1.05x faster than old (regex-based)
@tanstack/router-core new (character-based) - Wildcard Paths ($) - wildcard with prefix
1.19x faster than old (regex-based)
@tanstack/router-core new (character-based) - Mixed Complex Paths - mixed complex
1.49x faster than old (regex-based)
@tanstack/router-core new (character-based) - all paths combined - Aggregate: All Path Types
1.26x faster than old (regex-based) - all paths combined

Summary by CodeRabbit

  • Refactor
    • Reworked internal route-segment parsing to use a simpler brace-based approach, improving maintainability and parsing reliability while preserving existing public behavior.
    • Reduced complexity and optimized control flow, which should yield modest performance and validation improvements for route handling.

✏️ Tip: You can customize this high-level summary in your review settings.

@coderabbitai

coderabbitaiBot commented Jan 23, 2026

Copy link
Copy Markdown
Contributor
📝 Walkthrough

Walkthrough

Replaced regex-driven parsing with brace-position detection in the router segment parser. parseSegment now uses getOpenAndCloseBraces to identify optional parameters, wildcards, and regular parameters, performing position-based validation and computing segment boundaries.

Changes

Cohort / File(s)Summary
Parameter Parsing Optimization
packages/router-core/src/new-process-route-tree.ts
Removed three precompiled regexes and added getOpenAndCloseBraces. parseSegment now branches on brace positions to handle optional params ({-$name}), wildcards ({$}), and regular params ({$name}), with explicit validation and index calculations; falls back to pathname parsing if no braces match.

Sequence Diagram(s)

(omitted — changes are internal parsing logic within a single module and do not introduce multi-component flows)

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

Suggested labels

performance

Suggested reviewers

  • schiller-manuel
  • nlynzaad

Poem

A rabbit nibbles at tangled regex,
Finds braces instead and skips the stress.
Hops through segments, neat and spry,
Parsing paths with a brighter eye. 🐇✨

🚥 Pre-merge checks | ✅ 2 | ❌ 1
❌ Failed checks (1 warning)
Check nameStatusExplanationResolution
Docstring Coverage⚠️ WarningDocstring coverage is 50.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 nameStatusExplanation
Title check✅ PassedThe title accurately describes the main change: refactoring parseSegment to improve performance by eliminating regex-based parsing and using character-based parsing instead.
Description Check✅ PassedCheck skipped - CodeRabbit’s high-level summary is enabled.

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

✨ Finishing touches
  • 📝 Generate docstrings

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

@nx-cloud

nx-cloudBot commented Jan 23, 2026

Copy link
Copy Markdown
Contributor

View your CI Pipeline Execution ↗ for commit f1f2fbf

CommandStatusDurationResult
nx affected --targets=test:eslint,test:unit,tes...✅ Succeeded12m 5sView ↗
nx run-many --target=build --exclude=examples/*...✅ Succeeded1m 43sView ↗

☁️ Nx Cloud last updated this comment at 2026-01-23 16:43:04 UTC

@pkg-pr-new

pkg-pr-newBot commented Jan 23, 2026

Copy link
Copy Markdown
More templates

@tanstack/arktype-adapter

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

@tanstack/eslint-plugin-router

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

@tanstack/history

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

@tanstack/nitro-v2-vite-plugin

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

@tanstack/react-router

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

@tanstack/react-router-devtools

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

@tanstack/react-router-ssr-query

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

@tanstack/react-start

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

@tanstack/react-start-client

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

@tanstack/react-start-server

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

@tanstack/router-cli

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

@tanstack/router-core

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

@tanstack/router-devtools

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

@tanstack/router-devtools-core

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

@tanstack/router-generator

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

@tanstack/router-plugin

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

@tanstack/router-ssr-query-core

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

@tanstack/router-utils

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

@tanstack/router-vite-plugin

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

@tanstack/solid-router

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

@tanstack/solid-router-devtools

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

@tanstack/solid-router-ssr-query

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

@tanstack/solid-start

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

@tanstack/solid-start-client

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

@tanstack/solid-start-server

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

@tanstack/start-client-core

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

@tanstack/start-fn-stubs

npm i https://pkg.pr.new/TanStack/router/@tanstack/start-fn-stubs@6470

@tanstack/start-plugin-core

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

@tanstack/start-server-core

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

@tanstack/start-static-server-functions

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

@tanstack/start-storage-context

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

@tanstack/valibot-adapter

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

@tanstack/virtual-file-routes

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

@tanstack/vue-router

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

@tanstack/vue-router-devtools

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

@tanstack/vue-router-ssr-query

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

@tanstack/vue-start

npm i https://pkg.pr.new/TanStack/router/@tanstack/vue-start@6470

@tanstack/vue-start-client

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

@tanstack/vue-start-server

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

@tanstack/zod-adapter

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

commit: f1f2fbf

@coderabbitaicoderabbitaiBot 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.

Actionable comments posted: 1

🤖 Fix all issues with AI agents
In `@packages/router-core/src/new-process-route-tree.ts`:
- Around line 119-172: The parsed brace indices (openBrace, closeBrace,
paramStart, dollarPos, afterDollar, etc.) are offsets inside part but are being
written into output as if they were absolute positions in path; add the start
offset when writing any brace-based positions into output so the output indexes
are absolute. Specifically, in the branches that set output[...] for
SEGMENT_TYPE_OPTIONAL_PARAM, SEGMENT_TYPE_WILDCARD and SEGMENT_TYPE_PARAM,
replace uses of openBrace, closeBrace, paramStart, dollarPos, afterDollar and
closeBrace + 1 with openBrace + start, closeBrace + start, paramStart + start,
dollarPos + start, afterDollar + start and (closeBrace + 1) + start respectively
(leave path.length and end as-is). Ensure all three branches (optional param,
wildcard, regular param) consistently apply the start offset so prefix/suffix
extraction uses absolute indexes.

Comment threadpackages/router-core/src/new-process-route-tree.ts
@Sheraff
Sheraff merged commit 12a7288 into mainJan 23, 2026
6 checks passed
@Sheraff
Sheraff deleted the refactor-router-core-parse-segments-perf-no-regex branch January 23, 2026 22:28
Sign up for freeto 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

@Sheraff