为什么想到要折腾打包
原因是被吐槽了一波,说页面加载太慢了,所以想着对系统做一下性能优化。由于是个老系统,懒得动里面的请求和一些加载策略了。就想着能不能从打包上下手改动一下。
打包分析
1.处理moment
从这里看出,目前vendor包的大小是754kb,除了
element-ui之外,第二大的就是moment这个依赖了。仔细分析一下发现moment里面最多的好像就是这个locale语言包了。但是这个系统只有中英两个呀,所以在这里可以选择只留下zh-cn和en-gb两个语言包。这里可以引入一个插件moment-locales-webpack-plugin来帮我解决这个问题。
npm install moment-locales-webpack-plugin -D
然后在webpack配置中加入
const MomentLocalesPlugin = require('moment-locales-webpack-plugin');
...
plugins: [
new MomentLocalesPlugin({localesToKeep: ['zh-cn', 'en-gb']}),
]
这样处理完以后咱们再瞅瞅打包大小,减少了30kb。
2、对于业务不必要的包用cdn引入
继续分析一下,包的内容,发现vconsole这个东西对于业务没什么作用,好像没必要打到包里面,用cdn引入好像就可以了。然后只在非生产环境初始化就行。一下子又可以砍掉几十kb。
<script src='https://cdn.jsdelivr.net/npm/vconsole@latest/dist/vconsole.min.js'></script>
<script>
if (window.location.host !== 'prod.com') {
const vConsole = new VConsole();
}
</script>
3、工具库按需引入
做完上一步后,打包的大小就只有659kb了。然后继续看打包结果发现有两个东西好像可以按需引入啊。
lodash和crypto-js只需要里面的部分内容就可以了,好像没有必要全部都打到项目里面来。于是在代码里做了如下改动。
// lodash原来是这么用的
import _ from 'lodash'
const xxx = _.reduce();
...
// 修改以后是这么用的
import { reduce } from 'lodash/reduce';
const xxx = reduce();
---
// crypto-js原来是这么用的
import crypto from 'crypto-js';
const xxx = crypto.md5(yyy)
...
// 修改以后是这么用的
import { md5 } from 'crypto-js/md5'
const xxx = md5(yyy)
这样修改完以后,这两个包只剩下1kb出头和2.5kb的大小了,又给抠出来几十kb。
4、处理第三方库的共同依赖重复打包
从打包分析图看出,bn.js被打了好多次。
因为 webpack 在递归查找依赖的时候会默认去第三方库的 node_modules 目录中查找并单独打包,所以每个库只要对 bn.js 有依赖就会单独打包一次。解决这个问题可以配置webpack的alias别名来告诉webpack,查找依赖时遇到bn.js就去 nodejs的命令执行目录的node_modules目录中查找依赖。这样webpack不管遇到多少次bn.js都会识别为同一个依赖,也就只会打包一次了。
alias: {
'bn.js': path.resolve(process.cwd(), 'node_modules', 'bn.js')
}
这里用process.cwd()就是把依赖的查找目录指向当前 npm 命令的执行目录,也就是我们的项目根目录下的 node_modules 目录。
最后
最后的大小就是570kb了