Skip to content

Commit d21bb9f

Browse files
javivelascoijjk
andauthoredFeb 6, 2024··
[next] Preload common chunks (#11126)
This PR adds requiring the modules that _we know_ will be required in the Next.js Lambda in the module scope in a attempt to make a better use of resources. --------- Co-authored-by: JJ Kasper <jj@jjsweb.site>
1 parent ab24444 commit d21bb9f

File tree

3 files changed

+81
-1
lines changed

3 files changed

+81
-1
lines changed
 

‎.changeset/lazy-trees-bake.md

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'@vercel/next': patch
3+
---
4+
5+
Load common chunks on module initialization

‎packages/next/src/server-build.ts

+74-1
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,30 @@ const NEXT_DATA_MIDDLEWARE_RESOLVING_VERSION = 'v12.1.7-canary.33';
7070
const EMPTY_ALLOW_QUERY_FOR_PRERENDERED_VERSION = 'v12.2.0';
7171
const CORRECTED_MANIFESTS_VERSION = 'v12.2.0';
7272

73+
// Ideally this should be in a Next.js manifest so we can change it in
74+
// the future but this also allows us to improve existing versions
75+
const PRELOAD_CHUNKS = {
76+
APP_ROUTER_PAGES: [
77+
'.next/server/webpack-runtime.js',
78+
'next/dist/client/components/action-async-storage.external.js',
79+
'next/dist/client/components/request-async-storage.external.js',
80+
'next/dist/client/components/static-generation-async-storage.external.js',
81+
'next/dist/compiled/next-server/app-page.runtime.prod.js',
82+
],
83+
APP_ROUTER_HANDLER: [
84+
'.next/server/webpack-runtime.js',
85+
'next/dist/compiled/next-server/app-route.runtime.prod.js',
86+
],
87+
PAGES_ROUTER_PAGES: [
88+
'.next/server/webpack-runtime.js',
89+
'next/dist/compiled/next-server/pages.runtime.prod.js',
90+
],
91+
PAGES_ROUTER_API: [
92+
'.next/server/webpack-api-runtime.js',
93+
'next/dist/compiled/next-server/pages-api.runtime.prod.js',
94+
],
95+
};
96+
7397
// related PR: https://github.com/vercel/next.js/pull/52997
7498
// and https://github.com/vercel/next.js/pull/56318
7599
const BUNDLED_SERVER_NEXT_VERSION = 'v13.5.4';
@@ -1068,9 +1092,58 @@ export async function serverBuild({
10681092
}
10691093
}
10701094

1095+
let launcherData = group.isAppRouter ? appLauncher : launcher;
1096+
let preloadChunks: string[] = [];
1097+
1098+
if (process.env.VERCEL_NEXT_PRELOAD_COMMON === '1') {
1099+
const nextPackageDir = path.dirname(
1100+
resolveFrom(projectDir, 'next/package.json')
1101+
);
1102+
1103+
if (group.isPages) {
1104+
preloadChunks = PRELOAD_CHUNKS.PAGES_ROUTER_PAGES;
1105+
} else if (group.isApiLambda) {
1106+
preloadChunks = PRELOAD_CHUNKS.PAGES_ROUTER_API;
1107+
} else if (group.isAppRouter && !group.isAppRouteHandler) {
1108+
preloadChunks = PRELOAD_CHUNKS.APP_ROUTER_PAGES;
1109+
} else if (group.isAppRouteHandler) {
1110+
preloadChunks = PRELOAD_CHUNKS.APP_ROUTER_HANDLER;
1111+
}
1112+
const normalizedPreloadChunks: string[] = [];
1113+
1114+
for (const preloadChunk of preloadChunks) {
1115+
const absoluteChunk = preloadChunk.startsWith('.next')
1116+
? path.join(projectDir, preloadChunk)
1117+
: path.join(nextPackageDir, '..', preloadChunk);
1118+
1119+
// ensure the chunks are actually in this layer
1120+
if (
1121+
group.pseudoLayer[
1122+
path.join('.', path.relative(baseDir, absoluteChunk))
1123+
]
1124+
) {
1125+
normalizedPreloadChunks.push(
1126+
// relative files need to be prefixed with ./ for require
1127+
preloadChunk.startsWith('.next')
1128+
? `./${preloadChunk}`
1129+
: preloadChunk
1130+
);
1131+
}
1132+
}
1133+
1134+
if (normalizedPreloadChunks.length > 0) {
1135+
launcherData = launcherData.replace(
1136+
'// @preserve next-server-preload-target',
1137+
normalizedPreloadChunks
1138+
.map(name => `require('${name}');`)
1139+
.join('\n')
1140+
);
1141+
}
1142+
}
1143+
10711144
const launcherFiles: { [name: string]: FileFsRef | FileBlob } = {
10721145
[path.join(path.relative(baseDir, projectDir), '___next_launcher.cjs')]:
1073-
new FileBlob({ data: group.isAppRouter ? appLauncher : launcher }),
1146+
new FileBlob({ data: launcherData }),
10741147
};
10751148
const operationType = getOperationType({ group, prerenderManifest });
10761149

‎packages/next/src/server-launcher.ts

+2
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,8 @@ if (process.env.NODE_ENV !== 'production' && region !== 'dev1') {
2323
// eslint-disable-next-line
2424
const NextServer = require('__NEXT_SERVER_PATH__').default;
2525

26+
// @preserve next-server-preload-target
27+
2628
// __NEXT_CONFIG__ value is injected
2729
declare const __NEXT_CONFIG__: any;
2830
const conf = __NEXT_CONFIG__;

0 commit comments

Comments
 (0)
Please sign in to comment.