diff --git a/.changeset/steady-loops-compile.md b/.changeset/steady-loops-compile.md new file mode 100644 index 0000000000..5a243a4205 --- /dev/null +++ b/.changeset/steady-loops-compile.md @@ -0,0 +1,5 @@ +--- +'@tanstack/router-core': patch +--- + +Collect search middlewares with a counted loop so the optimized code stays valid across navigations. This removes a JIT recompilation that raised peak memory in the interrupted-navigations client memory benchmark. diff --git a/packages/router-core/src/router.ts b/packages/router-core/src/router.ts index 19ea2b8aed..b12e5df297 100644 --- a/packages/router-core/src/router.ts +++ b/packages/router-core/src/router.ts @@ -2900,14 +2900,17 @@ function needsInheritedParams( const EMPTY_RECORD: Record = Object.freeze({}) // Keep this separate from recursive execution to limit JIT compiler memory. +// A counted loop instead of `for...of`: Maglev's inlined array iteration +// deoptimizes on route option shapes and recompiles later, whereas indexed +// reads stay optimized once compiled. function getSearchMiddlewares( destRoutes: ReadonlyArray, includeValidateSearch: boolean | undefined, ) { const middlewares = [] as Array> - for (const route of destRoutes) { - const routeOptions = route.options + for (let i = 0; i < destRoutes.length; i++) { + const routeOptions = destRoutes[i]!.options if ('search' in routeOptions) { if (routeOptions.search?.middlewares) { middlewares.push(...routeOptions.search.middlewares)