Prefetch and preload from entry chunk. - #7444
Conversation
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.
|
For maintainers only:
|
|
I'm having some trouble adding tests, since the code executes during bootstrap. The tests in #7056 work because the FakeDocument is installed before the associated code that adds prefetch links executes. |
Rather than calling the prefetch function on its own during bootstrap, this change exposes the function as a function that can be called from the compiled code.
|
Even changing the code to not automatically call the prefetch itself, I can't access the function from the prefetch-preload tests, since it clears out the As far as I can find, none of the existing tests test anything like this (a publicly exposed function), so I don't have good examples to base my tests off of. |
|
Ok I see what you want to do. Let's solve this a bit different. I'm not happy with exposing an extra function, but I would be ok to enable triggering prefetch on bootstrap. preload has a different meaning and triggering it on bootstrap would change the semantics (it only makes sense as We can add this behavior in a back-compat way without extra option.
Why is this backward-compatible?
|
|
@sokra I updated the change to match what (I interpreted) you suggested. I even added a small optimization to split the chunkPrefetchMap among all the chunks, rather than loading it all upfront in the entry chunk. However, I'm still running into test issues, because the bootstrap code is called before the |
Good idea.
We could move this into the ConfigTestCases.test.js file. |
| `webpackJsonpCallback([${JSON.stringify( | ||
| chunk.ids | ||
| )}, {}, null, ${JSON.stringify( | ||
| chunk.getChildIdsByOrders().prefetch |
There was a problem hiding this comment.
Check of chunk.getChildIdsByOrders().prefetch is not empty
| if (entries.length > 0) { | ||
| source.add(`,${JSON.stringify(entries)}`); | ||
| } else { | ||
| source.add(`,null`); |
There was a problem hiding this comment.
This could be omitted when chunk.getChildIdsByOrders().prefetch is empty.
I don't want to increase chunk size if prefetching isn't used.
Also use 0 instead of null, that's shorter. (a bit)
| "var chunkIds = data[0];", | ||
| "var moreModules = data[1];", | ||
| withDefer ? "var executeModules = data[2];" : "", | ||
| "var prefetchChunks = data[3] || []", |
There was a problem hiding this comment.
Similar to withDefer check if we need this code.
| return source; | ||
| } | ||
| ); | ||
| mainTemplate.hooks.beforeStartup.tap( |
There was a problem hiding this comment.
Trigger prefetching after the startup code runs. This would omit prefetching when import() is used in initialization code.
There was a problem hiding this comment.
Where? There's no afterStartup hook, and startup includes a return statement that prevents later code from executing.
| Asset Size Chunks Chunk Names | ||
| 9ac13fb7087e9ff1b93e.js 1.05 KiB 0 [emitted] | ||
| f2e891598128a57b072c.js 11 KiB 1 [emitted] | ||
| f2e891598128a57b072c.js 11.6 KiB 1 [emitted] |
There was a problem hiding this comment.
bundle size of most of these test cases shouldn't increase, since prefetching isn't used. We don't want to users to pay for not using this feature.
There was a problem hiding this comment.
Following most of the other comments, I was able to eliminate most of the differences. However, to not emit blank lines when not using prefetching, I followed a different pattern than the rest of the code:
"var moreModules = data[1];",
withDefer ? "var executeModules = data[2];" : "",
...(withPrefetch ? ["var prefetchChunks = data[3] || []"] : []),
'// add "moreModules" to the modules object,',|
PR looks good |
This reverts commit 23ab98d.
- [x] Don't emit prefetch code if not needed - [x] Only affect StatsTestCase dealing with prefetching - [x] Fix existing prefetch test case - [ ] Trigger prefetch after startup code runs - [ ] Add new test(s)
|
Trying to add I was also unclear on your statement about:
as I replied to above. Lastly, I'm headed out on vacation for the next week, so I may not be able to pick this back up until the week after next. |
minor style issues add test case
This makes more sense as startup could take a while and we can use the time to fetch some resources
85d5228 to
c77ec39
Compare
|
Thank you for your pull request! The most important CI builds succeeded, we’ll review the pull request soon. |
|
Thanks |
|
I've created an issue to document this in webpack/webpack.js.org. |
|
Could this feature be used, or better not, as long as it still undocumented? |
Following up on @sokra's work in #7056, this change addresses #7084 to have webpack prefetch and preload designated chunks from the entry chunk. It adds a function (with its name configurable by
output.entryPrefetchFunction) that can be called by consuming code to trigger the prefetch/preload.What kind of change does this PR introduce?
I would call it a bugfix; @sokra may disagree.
Did you add tests for your changes?
I have not yet added tests; I will work on them, but wanted to get feedback on the design first.
Does this PR introduce a breaking change?
No
What needs to be documented once your changes are merged?
Any documentation (which I could not locate in this repro) that references
webpackPreloadorwebpackPrefetchshould no longer add the caveat about not working from the entry chunk.Additionally, with my second commit, need to document the
output.entryPrefetchFunctionoption.