prefetch
and preload
usage is good way to optimize website performance and user experience, this article introduce method to prefetch and preload, and fullfil with webpack
Link Type
rel
property of <link>
tag is used to defined link type, and combined with href
can prefetch and preload corresponding resource. prefetch
is one of the link types
1 | <link rel="prefetch" herf="URL"> |
preload
is the other type, also use href to defined resource address, but besides handling pre fetch, it will resolve the resource, so the property as
need to be added, to indicate type of resource
1 | <link rel="preload" href="URL" as="MIME_TYPE"> |
Prefetch Resource
prefetch
indicates that in the following navigation (ie: next webpage), user may need to use corresponding resource, and give a hint to browser that corresponding resource need to be gotten when idle
First create a new diretory prefetch-preload-demo
(all the code in this article will create here), install the associated dependencies, and create new directory static
mkdir prefetch-preload-demo
cd prefetch-preload-demo
npm init -y
npm i -D http-server
mkdir static
In static directory, create prefetch.html
, main.js
and script.js
prefetch.html
defined a link with prefetch
as rel
1 | <html> |
main.js
create a button, and bind click event
1 | let button = document.createElement('button'); |
script.js
just simply print
1 | console.log('script run'); |
Run the sever (or add server
script in package.json
)
npx http-server
Access http://localhost:8080 and navigate to static
, click prefetch.html, or directly visit online webpage, in the initial status, check the network tab of devtool, as the following image (don’t check Disable Cache
, click the gear on the right, check Use large request rows
)
script.js
is fetched, the two number in the size column, 275 B shows the download size, 0 B shows the resolved size (which means that it’s not been resolved yet)- Console tab is empty, which means script has not run yet
Click Add Script
on the page, <script>
tag with address script.js
will be added on the page, and the following content will been added on the network tab
- Download size become
(prefetch cache)
, which means that the resource is directly gotten from prefetch cache, and the resolved size below is no longer 0 - The debug content is printed on the console, which means that the script is resolved and run just now
Preload Resource
preload
indicates that in the current navigation (mostly the current webpage), user very likely need to use corresponding resource, and give a hint to browser that corresponding resource need to be gotten preferentially
Change prefetch in link tag of prefetch.html to preload
, and set resource type as
to script
, which form preload.html
1 | <link rel="preload" href="script.js" as="script"> |
Access the local server corresponding prefetch.html
, or directly access online webpage, in the initial status, check the network tag of devtool
script.js
is downloaded preferentially, the resolved size of size column is no longer 0, namelypreload
no only download the script, but also resolve it- The console tab is still empty, namely although the script is resolved, it has not run yet
Click Add Script
, there is not additional record in the network tab, but the console output the print content of script
- Because script is resolved completely, there is even no need to fetch from cache, just directly run
- If
Add Script
is not clicked in 3 second, the console will output warning, because the resource which should be loaded preferentially is not used in timeThe resource https://chanvinxiao.com/demo/html/script.js was preloaded using link preload but not used within a few seconds from the window’s load event. Please make sure it has an appropriate
as
value and it is preloaded intentionally.
webpack associated handling
Run the following command to install corresponding dependencies, and create new directory src
npm i -D webpack webpack-cli html-webpack-plugin preload-webpack-plugin@3.0.0-beta.4
mkdir src
- Current version of PreloadWebpackPlugin is 2.x, which is not compatible with current version of webpack which is 4.x, so need to specify the version as the newest 3.x beta
copy main.js
and script.js
to src, and modify the click event handler in main.js
to the following
1 | button.addEventListener('click', e => { |
- import() will load script dynamically, webpack will generate code which create
script
tag similar to above - The comment in import is magical comment with special meaning, and if webpackChunkName is not set, the imported script will name with number sequence
Add webpack.config.js
as following
1 | const HtmlWebpackPlugin = require('html-webpack-plugin'); |
- HtmlWebpackPlugin will generate corresponding html file automatically, index.html as default, here we change it via option
filename
- PreloadWebpackPlugin is plugin of HtmlWebpackPlugin, it will add
link
tag with link type aspreload
for the dynamically imported resource, and theas
value can be determined by the suffix
PreloadWebpackPlugin also support prefetch, with rel
option as prefetch
1 | new HtmlWebpackPlugin({ |
But if we want to generate both preload.html and prefetch.html, option excludeHtmlNames
need to be set in the corresponding PreloadWebpackPlugin configuration, or else both preload and prefetch link tags will be produced simultaneously
1 | new HtmlWebpackPlugin({ |
Build files (or add build
script in package.json
)
npx webpack
prefetch.html and preload.html will be generated in dist
directory, access local server corresponding address, you will get the same effect as the above static page
Summarize
This article show the fulfillment of prefetch and preload with two methods: static page and webpack building. The complete code can be found in GitHub, the main technical points are as follow:
ELEMENT.appendChild
create script dynamicallyimport()
load script dynamically and set the magical comment- The configuration of
html-webpack-plugin
and its plugin