打包分析
我们可以使用打包分析工具来查看Webpack
打包的过程,Webpack
提供了许多分析工具,例如analyse
。
https://github.com/webpack/analyse
配置命令行参数:
{
// ...
"scripts": {
"dev": "webpack serve --config ./build/webpack.dev.js",
// webpack --profile --json > stats.json
"build:test": "webpack --profile --json > stats.json --config ./build/webpack.dev.js",
"build": "webpack --config ./build/webpack.prod.js"
},
// ...
}
然后就会生成stats.json
文件,此时的json
文件非常的长而且我们观看会非常的困难,访问analyse 网站且上传生成的stats.json
文件就能帮我们自动生成分析报告。
Webpack
还提供了其他的打包分析的交互图,详情Webpack
中文:
代码分离 | webpack 中文文档
Prefetch/Preload
Webpck
中文:
代码分离 | webpack 中文文档
我们在前面学习知道在使用optimization.splitChunks.chunks
默认值是async
,为什么不是all
呢?Webpack
期望我们写的代码是什么样子的呢?
// ...
module.exports = {
// ...
optimization: {
usedExports: true,
splitChunks: {
// 分割引入代码库的方式,默认为 async 异步,可选 all:同步和异步
chunks: 'all',
// 引入的代码库最小为20000字节
minSize: 20000,
minRemainingSize: 0,
maxSize: 100000,
// 代码库至少被引入1次
minChunks: 1,
// 同时加载的模块数最大是 30
maxAsyncRequests: 30,
maxInitialRequests: 30,
enforceSizeThreshold: 50000,
cacheGroups: {
defaultVendors: {
// 是否是 node_modules 下的代码库
test: /[\\/]node_modules[\\/]/,
priority: -10,
// 如果一个模块被打包过就不再进行打包
reuseExistingChunk: true,
},
default: {
minChunks: 2,
priority: -20,
reuseExistingChunk: true,
},
},
},
},
// ...
}
document.addEventListener("click", () => {
const element = document.createElement("div");
element.innerHTML = "Hello Word!";
document.body.appendChild(element);
})
这个时候运行打包命令npm run build:test
后查看index.html
页面就会空白的内容,随后点击就会发现出现了Hello Word
。这样看起来没有问题,这样的代码还能进行优化吗,答案是可以的。
异步加载click.js
:
document.addEventListener("click", () => {
import("./click.js").then(({ default: func }) => {
func();
})
})
export default function () {
const element = document.createElement("div");
element.innerHTML = "Hello Word!";
document.body.appendChild(element);
}
以上代码我们改写成了异步加载的方式,假如业务代码非常多的时候进行异步加载利用率就提高了很多,同时也会让页面加载时间缩短。
我们来看看慕课网的JS
文件加载情况。
整体的代码利用率还是非常不错的,但是我们可以看到页面总共加载了 793KB 的代码但实际使用 266KB 的代码,如果能把大部分代码改成异步加载的代码页面的加载会大大的提升,这就是Webpack
的配置代码默认为async
的原因。
我们在看一个场景:一个网站进入后,我们点击登录会弹窗一个登录的弹窗,实际上这个弹窗是不应该在首页加载的时候就加载进来的,我们可以在点击登录的时候异步加载弹窗,但是这时还有个问题,就是点击的时候进行异步加载弹窗会不会延迟卡顿呢?
prefetch
我们可以使用prefetch
进行加载弹窗的代码,prefetch
发现首页主要的JS
文件全部加载完毕后利用网络闲暇进行加载异步代码。
document.addEventListener("click", () => {
import( /* webpackPrefetch: true */ "./click.js").then(({ default: func }) => {
func();
})
})
preload
与prefetch
指令相比,preload
指令有许多不同之处:
preload chunk
会在父chunk
加载时,以并行方式开始加载;prefetch chunk
会在父chunk
加载结束后开始加载。preload chunk
具有中等优先级,并立即下载;prefetch chunk
在浏览器闲置时下载。preload chunk
会在父chunk
中立即请求,用于当下时刻。prefetch chunk
会用于未来的某个时刻。- 浏览器支持程度不同。
document.addEventListener("click", () => {
import( /* webpackPreload: true */ "./click.js").then(({ default: func }) => {
func();
})
})
Tip 不正确地使用
webpackPreload
会有损性能,请谨慎使用。