Skip to content

Commit eefacf3

Browse files
committed
Prefetch and preload from entry chunk.
Following up on @sokra's work in webpack#7056, this change addresses webpack#7084 to have webpack prefetch and preload designated chunks from the entry chunk.
1 parent 4f4a2ba commit eefacf3

File tree

2 files changed

+70
-29
lines changed

2 files changed

+70
-29
lines changed

lib/web/JsonpMainTemplatePlugin.js

Lines changed: 68 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,13 @@ class JsonpMainTemplatePlugin {
2828
}
2929
return false;
3030
};
31+
const needEntryChunkPrefetch = chunk => {
32+
const preloadMaps = chunk.getChildIdsByOrders();
33+
for (const preloadGroup of Object.keys(preloadMaps)) {
34+
if (preloadMaps[preloadGroup].length > 0) return true;
35+
}
36+
return false;
37+
};
3138
// TODO refactor this
3239
if (!mainTemplate.hooks.jsonpScript) {
3340
mainTemplate.hooks.jsonpScript = new SyncWaterfallHook([
@@ -106,6 +113,38 @@ class JsonpMainTemplatePlugin {
106113
contentHashType: "javascript"
107114
});
108115
};
116+
117+
const linkPreload = mainTemplate => {
118+
const crossOriginLoading = mainTemplate.outputOptions.crossOriginLoading;
119+
const jsonpScriptType = mainTemplate.outputOptions.jsonpScriptType;
120+
return Template.asString([
121+
"var link = document.createElement('link');",
122+
jsonpScriptType
123+
? `link.type = ${JSON.stringify(jsonpScriptType)};`
124+
: "",
125+
"link.charset = 'utf-8';",
126+
crossOriginLoading
127+
? `link.crossOrigin = ${JSON.stringify(crossOriginLoading)};`
128+
: "",
129+
`if (${mainTemplate.requireFn}.nc) {`,
130+
Template.indent(
131+
`link.setAttribute("nonce", ${mainTemplate.requireFn}.nc);`
132+
),
133+
"}",
134+
'link.rel = "preload";',
135+
'link.as = "script";',
136+
"link.href = jsonpScriptSrc(chunkId);"
137+
]);
138+
};
139+
140+
const linkPrefetch = () => {
141+
return Template.asString([
142+
"var link = document.createElement('link');",
143+
'link.rel = "prefetch";',
144+
"link.href = jsonpScriptSrc(chunkId);"
145+
]);
146+
};
147+
109148
mainTemplate.hooks.localVars.tap(
110149
"JsonpMainTemplatePlugin",
111150
(source, chunk, hash) => {
@@ -140,6 +179,33 @@ class JsonpMainTemplatePlugin {
140179
"}"
141180
);
142181
}
182+
if (needEntryChunkPrefetch(chunk)) {
183+
let preloadPrefetchChildren = chunk.getChildIdsByOrders();
184+
extraCode.push(
185+
"",
186+
"// preload or prefetch split chunks from entry chunk",
187+
"(function prefetchOrPreloadFromEntry() {",
188+
preloadPrefetchChildren.preload
189+
? Template.indent([
190+
`${JSON.stringify(
191+
preloadPrefetchChildren.preload
192+
)}.map(chunkId => {`,
193+
Template.indent([linkPreload(mainTemplate)]),
194+
`});`
195+
])
196+
: "",
197+
preloadPrefetchChildren.prefetch
198+
? Template.indent([
199+
`${JSON.stringify(
200+
preloadPrefetchChildren.prefetch || []
201+
)}.map(chunkId => {`,
202+
Template.indent([linkPrefetch()]),
203+
`});`
204+
])
205+
: "",
206+
"})();"
207+
);
208+
}
143209
if (extraCode.length === 0) return source;
144210
return Template.asString([source, ...extraCode]);
145211
}
@@ -205,38 +271,13 @@ class JsonpMainTemplatePlugin {
205271
mainTemplate.hooks.linkPreload.tap(
206272
"JsonpMainTemplatePlugin",
207273
(_, chunk, hash) => {
208-
const crossOriginLoading =
209-
mainTemplate.outputOptions.crossOriginLoading;
210-
const jsonpScriptType = mainTemplate.outputOptions.jsonpScriptType;
211-
212-
return Template.asString([
213-
"var link = document.createElement('link');",
214-
jsonpScriptType
215-
? `link.type = ${JSON.stringify(jsonpScriptType)};`
216-
: "",
217-
"link.charset = 'utf-8';",
218-
crossOriginLoading
219-
? `link.crossOrigin = ${JSON.stringify(crossOriginLoading)};`
220-
: "",
221-
`if (${mainTemplate.requireFn}.nc) {`,
222-
Template.indent(
223-
`link.setAttribute("nonce", ${mainTemplate.requireFn}.nc);`
224-
),
225-
"}",
226-
'link.rel = "preload";',
227-
'link.as = "script";',
228-
"link.href = jsonpScriptSrc(chunkId);"
229-
]);
274+
return linkPreload(mainTemplate);
230275
}
231276
);
232277
mainTemplate.hooks.linkPrefetch.tap(
233278
"JsonpMainTemplatePlugin",
234279
(_, chunk, hash) => {
235-
return Template.asString([
236-
"var link = document.createElement('link');",
237-
'link.rel = "prefetch";',
238-
"link.href = jsonpScriptSrc(chunkId);"
239-
]);
280+
return linkPrefetch();
240281
}
241282
);
242283
mainTemplate.hooks.requireEnsure.tap(

test/__snapshots__/StatsTestCases.test.js.snap

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1672,7 +1672,7 @@ exports[`StatsTestCases should print correct stats for prefetch 1`] = `
16721672
normal.js 130 bytes 1 [emitted] normal
16731673
prefetched2.js 127 bytes 2 [emitted] prefetched2
16741674
prefetched3.js 130 bytes 3 [emitted] prefetched3
1675-
main.js 9.73 KiB 4 [emitted] main
1675+
main.js 10.1 KiB 4 [emitted] main
16761676
inner.js 136 bytes 5 [emitted] inner
16771677
inner2.js 201 bytes 6 [emitted] inner2
16781678
Entrypoint main = main.js (prefetch: prefetched2.js prefetched.js prefetched3.js)
@@ -1705,7 +1705,7 @@ exports[`StatsTestCases should print correct stats for preload 1`] = `
17051705
normal.js 130 bytes 1 [emitted] normal
17061706
preloaded2.js 127 bytes 2 [emitted] preloaded2
17071707
preloaded3.js 130 bytes 3 [emitted] preloaded3
1708-
main.js 9.85 KiB 4 [emitted] main
1708+
main.js 10.4 KiB 4 [emitted] main
17091709
inner.js 136 bytes 5 [emitted] inner
17101710
inner2.js 201 bytes 6 [emitted] inner2
17111711
Entrypoint main = main.js (preload: preloaded2.js preloaded.js preloaded3.js)

0 commit comments

Comments
 (0)