Skip to content

Commit 9aff99a

Browse files
committed
add caching
1 parent b13dfdb commit 9aff99a

File tree

1 file changed

+41
-23
lines changed

1 file changed

+41
-23
lines changed

packages/nuxt/src/runtime/utils/route-extraction.ts

Lines changed: 41 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,30 @@ import { logger } from '@sentry/core';
22
import type { NuxtSSRContext } from 'nuxt/app';
33
import type { NuxtPage } from 'nuxt/schema';
44

5+
export type NuxtPageSubset = { path: NuxtPage['path']; file: NuxtPage['file'] };
6+
7+
// buildTimePagesData -> Map<file, path>
8+
const routeMappingCache = new WeakMap<NuxtPageSubset[], Map<string, string>>();
9+
10+
/**
11+
* Creates a mapping from module paths to parametrized routes for faster lookup.
12+
* The `buildTimePagesData` doesn't change during SSR, as it's generated at build time.
13+
*/
14+
function createRouteMapping(buildTimePagesData: NuxtPageSubset[]): Map<string, string> {
15+
const mapping = new Map<string, string>();
16+
17+
for (const routeData of buildTimePagesData) {
18+
if (routeData.file && routeData.path) {
19+
// Handle Unix and Windows paths
20+
const normalizedFile = routeData.file.replace(/\\/g, '/');
21+
mapping.set(normalizedFile, routeData.path);
22+
}
23+
}
24+
25+
routeMappingCache.set(buildTimePagesData, mapping);
26+
return mapping;
27+
}
28+
529
/**
630
* Extracts route information from the SSR context modules and URL.
731
*
@@ -17,12 +41,12 @@ import type { NuxtPage } from 'nuxt/schema';
1741
*
1842
* @param buildTimePagesData
1943
* An array of NuxtPage objects representing the build-time pages data.
20-
* Example: [{ name: 'some-path', path: '/some/path' }, { name: 'user-userId', path: '/user/:userId()' }]
44+
* Example: [{ file: '/a/file/pages/some/path', path: '/some/path' }, { file: '/a/file/pages/user/[userId].vue', path: '/user/:userId()' }]
2145
*/
2246
export function extractParametrizedRouteFromContext(
2347
ssrContextModules?: NuxtSSRContext['modules'],
2448
currentUrl?: NuxtSSRContext['url'],
25-
buildTimePagesData: NuxtPage[] = [],
49+
buildTimePagesData: NuxtPageSubset[] = [],
2650
): null | { parametrizedRoute: string } {
2751
if (!ssrContextModules || !currentUrl) {
2852
logger.warn('SSR context modules or URL is not available.');
@@ -35,30 +59,24 @@ export function extractParametrizedRouteFromContext(
3559

3660
const modulesArray = Array.from(ssrContextModules);
3761

38-
// Find the route data that corresponds to a module in ssrContext.modules
39-
const foundRouteData = buildTimePagesData.find(routeData => {
40-
if (!routeData.file) return false;
41-
42-
return modulesArray.some(module => {
43-
// Extract the folder name and relative path from the page file
44-
// e.g., 'pages/test-param/[param].vue' -> folder: 'pages', path: 'test-param/[param].vue'
45-
const filePathParts = module.split('/');
62+
const existingRouteMapping = routeMappingCache.get(buildTimePagesData);
63+
const routeMapping = existingRouteMapping || createRouteMapping(buildTimePagesData);
4664

47-
// Exclude root-level files (e.g., 'app.vue')
48-
if (filePathParts.length < 2) return false;
65+
const modulePagePaths = modulesArray.map(module => {
66+
const filePathParts = module.split('/');
67+
if (filePathParts.length < 2) return null;
4968

50-
// Normalize path separators to handle both Unix and Windows paths
51-
const normalizedRouteFile = routeData.file?.replace(/\\/g, '/');
52-
53-
const pagesFolder = filePathParts[0];
54-
const pageRelativePath = filePathParts.slice(1).join('/');
55-
56-
// Check if any module in ssrContext.modules ends with the same folder/relative path structure
57-
return normalizedRouteFile?.endsWith(`/${pagesFolder}/${pageRelativePath}`);
58-
});
69+
const pagesFolder = filePathParts[0];
70+
const pageRelativePath = filePathParts.slice(1).join('/');
71+
return `/${pagesFolder}/${pageRelativePath}`;
5972
});
6073

61-
const parametrizedRoute = foundRouteData?.path ?? null;
74+
for (const [pageFile, route] of routeMapping) {
75+
// Check if any module of the requested page ends with the same folder/relative path structure as the parametrized filePath from build time.
76+
if (modulePagePaths.some(filePath => filePath && pageFile.endsWith(filePath))) {
77+
return { parametrizedRoute: route };
78+
}
79+
}
6280

63-
return parametrizedRoute === null ? null : { parametrizedRoute };
81+
return null;
6482
}

0 commit comments

Comments
 (0)