From f6a6182f3c78a0b06f4db01c3e98a8d3fd75778d Mon Sep 17 00:00:00 2001 From: Claude Date: Sat, 31 Oct 2026 10:34:09 +0000 Subject: [PATCH 1/2] perf(router): build a prefix matcher's literal text in its parsing loop createPrefixMatcher found its literal-only prefix with `every` and then `map` + `join`, two arrow functions a cold start compiles on the first call. Building the text in the loop that already walks the prefix spares them. The text stays in a `const`, so V8 still folds it into the matcher. Creating the first matcher costs 10% fewer instructions, 20 matchers 13% fewer; matching is unchanged. Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_01VVaw7ReSePbVFG3kzDy1FQ --- packages/router/src/index.ts | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/packages/router/src/index.ts b/packages/router/src/index.ts index 6311d33..cd45ac9 100644 --- a/packages/router/src/index.ts +++ b/packages/router/src/index.ts @@ -279,25 +279,31 @@ function addStatic( */ export function createPrefixMatcher(prefix: `/${string}`): (pathname: `/${string}`) => boolean { const head: (string | undefined)[] = [] + // Built in this loop rather than with `every` and `map`, which a cold start + // would compile as two more functions. + let text: string | undefined = '' for (const segment of parse(prefix)) { if (typeof segment === 'string') { head.push(segment) + if (segment === '' || segment.includes('/')) { + text = undefined + } else if (text !== undefined) { + text += '/' + segment + } } else if (segment.catchAll) { break } else { head.push(undefined) + text = undefined } } // oRPC tests each pending lazy router's prefix on every request, so a prefix // of only literal text is compared at once for a path without `%`, and other - // paths are read only as far as the prefix goes. - const literal = head.every( - (segment) => segment !== undefined && segment !== '' && !segment.includes('/'), - ) - ? head.map((segment) => `/${segment}`).join('') - : undefined + // paths are read only as far as the prefix goes. A `const` lets V8 fold it + // into the matcher. + const literal = text return (pathname) => { if (literal !== undefined && !pathname.includes('%')) { From a93efd34770e5b986c381f90ca18d315f3d0dbf7 Mon Sep 17 00:00:00 2001 From: Claude Date: Sat, 31 Oct 2026 10:51:22 +0000 Subject: [PATCH 2/2] perf(router): walk prefix segments outside the prefix matcher A prefix matcher compares a literal-only prefix with one startsWith, but its closure also held the segment-by-segment walk for other prefixes and for paths with `%`. V8 compiles a function whole on its first call, so a cold start compiled the walk for every app with literal lazy-router prefixes. Moving the walk to `matchesHead` keeps the closure small. For 5 literal prefixes, creating the matchers costs 8% fewer instructions and their first call 52% fewer. Steady matching is unchanged for literal prefixes and up to 0.3% slower for prefixes with params; importing costs about 18k instructions more. Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_01VVaw7ReSePbVFG3kzDy1FQ --- packages/router/src/index.ts | 43 ++++++++++++++++++++++-------------- 1 file changed, 26 insertions(+), 17 deletions(-) diff --git a/packages/router/src/index.ts b/packages/router/src/index.ts index cd45ac9..6b6221c 100644 --- a/packages/router/src/index.ts +++ b/packages/router/src/index.ts @@ -313,30 +313,39 @@ export function createPrefixMatcher(prefix: `/${string}`): (pathname: `/${string ) } - let start = 1 + return matchesHead(head, pathname) + } +} - for (const expected of head) { - // At the end, or at a trailing slash, the path has no more segments. - if (start >= pathname.length) { - return false - } +/** + * Whether `pathname` starts with the segments in `head`, `undefined` standing + * for a param. Kept out of the prefix matcher, so that a cold start compiles it + * only for a prefix with params or a path with `%`. + */ +function matchesHead(head: readonly (string | undefined)[], pathname: string): boolean { + let start = 1 - let end = pathname.indexOf('/', start) - if (end === -1) { - end = pathname.length - } + for (const expected of head) { + // At the end, or at a trailing slash, the path has no more segments. + if (start >= pathname.length) { + return false + } - // `undefined` stands for a param, which needs a non-empty segment. - const segment = decode(pathname.slice(start, end)) - if (expected === undefined ? segment === '' : segment !== expected) { - return false - } + let end = pathname.indexOf('/', start) + if (end === -1) { + end = pathname.length + } - start = end + 1 + // `undefined` stands for a param, which needs a non-empty segment. + const segment = decode(pathname.slice(start, end)) + if (expected === undefined ? segment === '' : segment !== expected) { + return false } - return true + start = end + 1 } + + return true } function filterOf(statics: Map): Uint8Array {