打包分析
我们可以使用打包分析工具来查看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,// 同时加载的模块数最大是 30maxAsyncRequests: 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会有损性能,请谨慎使用。
