From 11f7697005e773cf3d88c7b6cd573f8ee292d644 Mon Sep 17 00:00:00 2001 From: Claude Date: Thu, 29 Oct 2026 11:10:13 +0000 Subject: [PATCH] perf(router): copy new tree nodes from one empty node An object literal with `undefined` values is not a constant V8 can clone: it creates the object, then defines each property with its own IC, seven per node. Spreading one empty node copies it in one step instead. The nodes keep their fields and `undefined`, so the code that reads them, and the steady state, stay the same. Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_01VVaw7Sutbw6xMTMyDFeNfw --- packages/router/src/index.ts | 35 +++++++++++++++++++---------------- 1 file changed, 19 insertions(+), 16 deletions(-) diff --git a/packages/router/src/index.ts b/packages/router/src/index.ts index 51739f4..1205cc5 100644 --- a/packages/router/src/index.ts +++ b/packages/router/src/index.ts @@ -91,6 +91,21 @@ const PARAM_NAME = /^[\w-]+$/ const FILTER_AFTER = 1024 +/** + * Each node starts as a copy of this one, which V8 makes in one step. An + * object literal with `undefined` values would define each property in turn, + * which adds up while a cold start builds the tree. + */ +const EMPTY_NODE: Readonly> = { + literals: undefined, + literal: undefined, + literalNode: undefined, + param: undefined, + catchAlls: undefined, + route: undefined, + pending: undefined, +} + /** * Matches request paths against OpenAPI path templates, the way oRPC routes * them: @@ -229,7 +244,7 @@ function routesOf(methods: Map>, method: string): Met let routes = methods.get(method) if (routes === undefined) { routes = { - root: createNode(), + root: { ...EMPTY_NODE }, statics: new Map(), filter: undefined, unfiltered: 0, @@ -421,7 +436,7 @@ function expand(node: Node, pending: unknown[], start: number, whole: bool } if (!segment.catchAll) { - child.param ??= createNode() + child.param ??= { ...EMPTY_NODE } child = child.param continue } @@ -471,7 +486,7 @@ function literalChild(node: Node, segment: string): Node { if (node.literals === undefined) { if (node.literalNode === undefined) { node.literal = segment - node.literalNode = createNode() + node.literalNode = { ...EMPTY_NODE } return node.literalNode } if (segment === node.literal) { @@ -485,24 +500,12 @@ function literalChild(node: Node, segment: string): Node { let child = node.literals.get(segment) if (child === undefined) { - child = createNode() + child = { ...EMPTY_NODE } node.literals.set(segment, child) } return child } -function createNode(): Node { - return { - literals: undefined, - literal: undefined, - literalNode: undefined, - param: undefined, - catchAlls: undefined, - route: undefined, - pending: undefined, - } -} - function parse(path: `/${string}`): Segment[] { return trimTrailingSlash(path).split('/').map(toSegment).slice(1) }