背景:
SPA 的 vue 应用, 采用 webpack2 构建, 打包入口为 main.js
输出: main 模块打包成 app.js, 公共 lib 打包成 vendor.js, 公共样式打包成 app.CSS, 运行时依赖打包成 mainfest.js, 路由页面动态加载, 输出以 ID 开头的 js 文件
缓存策略: 对所有输出的文件加载 hash 值, 服务器加上永久缓存的标志, 通过 hash 来判断是否有新文件
改造前 hash 值改变的场景:
1, 修改某个页面的业务代码: 只有对应页面 js 的 hash 值改变
2, 修改公共样式: 只有 app.css 文件的 hash 值改变
3, 增加页面(即在路由中动态导入模块): 所有模块的 hash 值都改变, 包括 app,vendor,mainfest 和所有页面的 js 模块文件 ×(不能忍, 会导致浏览器重新下载所有模块)
PS: 没测试过之前, 我一直以为不会改变所有的 hash 值....
3, 引入新库(即在 Main 中静态导入模块): 所有模块的 hash 值都改变, 包括 app,vendor,mainfest 和所有页面的 js 模块文件 ×(同上)
原因分析:
1, 默认情况下 webpack 的模块都是以一个有序数列命名的, 也就是[0,1,2....].
2, 当引入 / 删除模块时, 原有的顺序被打乱, 导致所有模块的 hash 值变动, 进而导致 chunkhash 改变.
上述场景[4] 为例:
app.js 因为内容变化 (引入新模块) 而变化
页面模块因为 module.id 变化 (新引入静态模块, 打乱顺序) 而变化
vendor 因为打包进的各个模块 module.id 发生变化
runtime 因为它维护依赖关系而变化
优化步骤:
1, 稳定 moduleId,
2, 稳定 chunkhash,(var WebpackChunkHash = require('webpack-chunk-hash');)
3, 去除命名中的 chunkId
优化后测试:
1, 修改某个页面的业务代码: 只有对应页面 js 的 hash 值改变
2, 修改公共样式: 只有 app.css 文件的 hash 值改变
3, 增加页面(即在路由中动态导入模块): 仅改变代码的 app 发生变化
4, 引入新库(即在 Main 中静态导入模块): 仅改变代码的 app 和打包新库的 vendor 发生变化 `
优化后的速度和压缩率 比对:
构建总时间(第一次) | 构建总时间(3 次平均) | 构建总大小(第一次) | 构建总大小(3 次平均) | |
初始 | 64849ms | 64882ms | 2.50MB | 2.50MB |
优化后 | 63867ms | 62276ms | 2.50MB | 2.50MB |
改动后构建速度和大小没有明显变化, 构建时间稍微减少 1~2 秒. 稳定 hash 不会对性能有影响.
来源: https://www.cnblogs.com/simleSmith/p/8716486.html