UPDATE
You can use preload-webpack-plugin with html-webpack-plugin it will let you define what to preload in configuration and it will automatically insert tags to preload your chunk
note if you are using webpack v4 as of now you will have to install this plugin using preload-webpack-plugin@next
example
plugins: [
new HtmlWebpackPlugin(),
new PreloadWebpackPlugin({
rel: 'preload',
include: 'asyncChunks'
})
]
For a project generating two async scripts with dynamically generated
names, such as chunk.31132ae6680e598f8879.js
and
chunk.d15e7fdfc91b34bb78c4.js
, the following preloads will be injected
into the document head
<link rel="preload" as="script" href="chunk.31132ae6680e598f8879.js">
<link rel="preload" as="script" href="chunk.d15e7fdfc91b34bb78c4.js">
UPDATE 2
if you don't want to preload all async chunk but only specific once you can do that too
either you can use migcoder's babel plugin or with preload-webpack-plugin
like following
first you will have to name that async chunk with help of webpack
magic comment
example
import(/* webpackChunkName: 'myAsyncPreloadChunk' */ './path/to/file')
and then in plugin configuration use that name like
plugins: [
new HtmlWebpackPlugin(),
new PreloadWebpackPlugin({
rel: 'preload',
include: ['myAsyncPreloadChunk']
})
]
First of all let's see the behavior of browser when we specify script
tag or link
tag to load the script
- whenever a browser encounter a
script
tag it will load it parse it
and execute it immediately
- you can only delay the parsing and evaluating with help of
async
and
defer
tag only until DOMContentLoaded
event
- you can delay the execution (evaluation) if you don't insert the script tag ( only preload it with
link
)
now there are some other not recommended hackey way is you ship your entire script and string
or comment
( because evaluation time of comment or string is almost negligible) and when you need to execute that you can use Function() constructor
or eval
both are not recommended
Another Approach Service Workers: ( this will preserve you cache event after page reload or user goes offline after cache is loaded )
In modern browser you can use service worker
to fetch and cache a recourse ( JavaScript, image, css anything ) and when main thread request for that recourse you can intercept that request and return the recourse from cache this way you are not parsing and evaluating the script when you are loading it into the cache
read more about service workers here
example
self.addEventListener('install', function(event) {
event.waitUntil(
caches.open('v1').then(function(cache) {
return cache.addAll([
'/sw-test/',
'/sw-test/index.html',
'/sw-test/style.css',
'/sw-test/app.js',
'/sw-test/image-list.js',
'/sw-test/star-wars-logo.jpg',
'/sw-test/gallery/bountyHunters.jpg',
'/sw-test/gallery/myLittleVader.jpg',
'/sw-test/gallery/snowTroopers.jpg'
]);
})
);
});
self.addEventListener('fetch', function(event) {
event.respondWith(caches.match(event.request).then(function(response) {
// caches.match() always resolves
// but in case of success response will have value
if (response !== undefined) {
return response;
} else {
return fetch(event.request).then(function (response) {
// response may be used only once
// we need to save clone to put one copy in cache
// and serve second one
let responseClone = response.clone();
caches.open('v1').then(function (cache) {
cache.put(event.request, responseClone);
});
return response;
}).catch(function () {
// any fallback code here
});
}
}));
});
as you can see this is not a webpack dependent thing this is out of scope of webpack however with help of webpack you can split your bundle which will help utilizing service worker better