@@ -38,7 +38,11 @@ import {
3838 executeRewriteOutput ,
3939 rewriteBasepath ,
4040} from './rewrite'
41- import type { ProcessedTree } from './new-process-route-tree'
41+ import type { LRUCache } from './lru-cache'
42+ import type {
43+ ProcessRouteTreeResult ,
44+ ProcessedTree ,
45+ } from './new-process-route-tree'
4246import type { SearchParser , SearchSerializer } from './searchParams'
4347import type { AnyRedirect , ResolvedRedirect } from './redirect'
4448import type {
@@ -872,6 +876,17 @@ export type CreateRouterFn = <
872876 TDehydrated
873877>
874878
879+ declare global {
880+ // eslint-disable-next-line no-var
881+ var __TSR_CACHE__ :
882+ | {
883+ routeTree : AnyRoute
884+ processRouteTreeResult : ProcessRouteTreeResult < AnyRoute >
885+ resolvePathCache : LRUCache < string , string >
886+ }
887+ | undefined
888+ }
889+
875890/**
876891 * Core, framework-agnostic router engine that powers TanStack Router.
877892 *
@@ -922,6 +937,7 @@ export class RouterCore<
922937 routesById ! : RoutesById < TRouteTree >
923938 routesByPath ! : RoutesByPath < TRouteTree >
924939 processedTree ! : ProcessedTree < TRouteTree , any , any >
940+ resolvePathCache ! : LRUCache < string , string >
925941 isServer ! : boolean
926942 pathParamsDecoder ?: ( encoded : string ) => string
927943
@@ -1026,7 +1042,28 @@ export class RouterCore<
10261042
10271043 if ( this . options . routeTree !== this . routeTree ) {
10281044 this . routeTree = this . options . routeTree as TRouteTree
1029- this . buildRouteTree ( )
1045+ let processRouteTreeResult : ProcessRouteTreeResult < TRouteTree >
1046+ if (
1047+ this . isServer &&
1048+ globalThis . __TSR_CACHE__ &&
1049+ globalThis . __TSR_CACHE__ . routeTree === this . routeTree
1050+ ) {
1051+ const cached = globalThis . __TSR_CACHE__
1052+ this . resolvePathCache = cached . resolvePathCache
1053+ processRouteTreeResult = cached . processRouteTreeResult as any
1054+ } else {
1055+ this . resolvePathCache = createLRUCache ( 1000 )
1056+ processRouteTreeResult = this . buildRouteTree ( )
1057+ // only cache if nothing else is cached yet
1058+ if ( this . isServer && globalThis . __TSR_CACHE__ === undefined ) {
1059+ globalThis . __TSR_CACHE__ = {
1060+ routeTree : this . routeTree ,
1061+ processRouteTreeResult : processRouteTreeResult as any ,
1062+ resolvePathCache : this . resolvePathCache ,
1063+ }
1064+ }
1065+ }
1066+ this . setRoutes ( processRouteTreeResult )
10301067 }
10311068
10321069 if ( ! this . __store && this . latestLocation ) {
@@ -1109,7 +1146,7 @@ export class RouterCore<
11091146 }
11101147
11111148 buildRouteTree = ( ) => {
1112- const { routesById , routesByPath , processedTree } = processRouteTree (
1149+ const result = processRouteTree (
11131150 this . routeTree ,
11141151 this . options . caseSensitive ,
11151152 ( route , i ) => {
@@ -1119,9 +1156,17 @@ export class RouterCore<
11191156 } ,
11201157 )
11211158 if ( this . options . routeMasks ) {
1122- processRouteMasks ( this . options . routeMasks , processedTree )
1159+ processRouteMasks ( this . options . routeMasks , result . processedTree )
11231160 }
11241161
1162+ return result
1163+ }
1164+
1165+ setRoutes ( {
1166+ routesById,
1167+ routesByPath,
1168+ processedTree,
1169+ } : ProcessRouteTreeResult < TRouteTree > ) {
11251170 this . routesById = routesById as RoutesById < TRouteTree >
11261171 this . routesByPath = routesByPath as RoutesByPath < TRouteTree >
11271172 this . processedTree = processedTree
@@ -1221,8 +1266,6 @@ export class RouterCore<
12211266 return location
12221267 }
12231268
1224- resolvePathCache = createLRUCache < string , string > ( 1000 )
1225-
12261269 /** Resolve a path against the router basepath and trailing-slash policy. */
12271270 resolvePathWithBase = ( from : string , path : string ) => {
12281271 const resolvedPath = resolvePath ( {
0 commit comments