大家好呀,每周都 GetMore ,只会越来越强。
最近在整理别人遗留的项目代码,感觉杂乱无章,有很多地方需要优化处理。借着这次机会把自己优化的经历整理给大家作为参考。网上也有很多打包性能优化的文章,但是每个项目的实际情况不太一样,不是搬过来直接用这么简单,让咱们开始吧
介绍下项目的环境:
- vue @2.6.11
- vue/cli @5.0.4
- webpack @4.46.0
项目的跑分情况
未优化的Lighthouse面板
未优化的webpack-bundle-analyzer面板
1 开发时打包速度优化
为了能够更好的开发,加上hard-source-webpack-plugin
这个插件,hard-source-webpack-plugin
是webpack的插件,为模块提供中间缓存步骤。为了查看结果,需要使用此插件运行webpack两次:第一次构建将花费正常的时间。第二次构建将显着加快(大概提升90%的构建速度)。
2 开启代码压缩
使用terser-webpack-plugin
插件
config.plugins.push(
new TerserPlugin({
cache: true,
parallel: true,
sourceMap: true,
terserOptions: {
compress: {
warnings: false,
drop_console: true,
drop_debugger: true,
pure_funcs: ['console.log']
}
}
})
)
3 包分析工具
使用webpack-bundle-analyzer
插件,在vue.config.js下的configureWebpack
配置项里加入以下代码
// 增加包分析工具, 运行analyz命令
if (process.env.npm_config_report) {
const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin
config.plugins.push(new BundleAnalyzerPlugin())
}
在package.json中加入
"scripts": {
...
"analyz": "NODE_ENV=production npm_config_report=true npm run build"
}
3.1 优化moment语言包,在configureWebpack
中加入以下配置
config.plugins.push(new webpack.IgnorePlugin(/^./locale$/, /moment$/))
3.2 去除echarts中world.json数据包,只引入china.json
3.3 如果在分析网页看板中有些包看着很大,或者有些没用到的资源也被打包进output中的话,就需要针对性的优化
4 tree-sharking优化
// vue.config.js 下的 configureWebpack
config.optimization = {
usedExports: true,
}
在package.json中加入
"sideEffects": [
"*.css",
"*.vue"
]
注意: 这两个配置和svg-sprite-loader
会冲突导致svg-icon丢失
5 depcheck 剔除未使用的npm包
5.1 安装depcheck
npm install -g depcheck
5.2 去到当前项目根目录执行depcheck
命令
Unused dependencies
* node-sass
...
Unused devDependencies
...
Missing dependencies
...
根据项目中的包依赖情况,重点处理Unused dependencies
下的包
6 vue-cli项目 ElementUI样式丢失
css: {
// 是否使用css分离插件 ExtractTextPlugin
extract: true,
// 开启 CSS source maps?
sourceMap: false,
// css预设器配置项
loaderOptions: {},
// 启用 CSS modules for all css
requireModuleExtension: true
},
7 svg-sprite-loader svg雪碧图
vue.config.js下的chainWebpack
中加入以下配置,在vue-cli项目中使用svg-icon
// set svg-sprite-loader
config.module
.rule('svg')
.exclude.add(resolve('src/assets/icons'))
.end()
config.module
.rule('icons')
.test(/.svg$/)
.include.add(resolve('src/assets/icons'))
.end()
.use('svg-sprite-loader')
.loader('svg-sprite-loader')
.options({
symbolId: 'icon-[name]'
})
.end()
8 将index.html中引入的一些在首屏使用不上的静态脚本资源,改成动态加载,自己写了个异步加载程序
sessionStorage.setItem('AsyncLoadScriptMap', '[]')
// 异步加载js文件的集合
const AsyncLoadJS = {
getMap: function() {
const map = sessionStorage.getItem('AsyncLoadJSMap');
if(!map) return []
return JSON.parse(map)
},
setItem: function(key) {
let map = sessionStorage.getItem('AsyncLoadJSMap') || '[]';
map = JSON.parse(map);
if(map.includes(key)) return;
map.push(key);
sessionStorage.setItem('AsyncLoadJSMap', JSON.stringify(map))
}
}
// 异步加载js文件
export function loadScript(url) {
return new Promise((resolve, reject) => {
if (AsyncLoadJS.getMap().includes(url)) {
resolve();
return true;
}
let script = document.createElement('script');
script.type = 'text/javascript';
script.charset = 'utf-8';
script.async = true;
script.src = url;
script.onerror = reject;
script.onload = function () {
AsyncLoadJS.setItem(url)
resolve();
}
document.head.appendChild(script);
})
}
9 在首页用不上的依赖在main.js中移除到对应模块,减少app.js主模块的文件大小
10 开启gzip,使用compression-webpack-plugin
插件
new CompressionWebpackPlugin({
algorithm: 'gzip',
test: /.(js|css)$/,
filename: '[path].gz[query]', // asset -> filename
threshold: 1024 * 10, // 达到10kb的静态文件进行压缩 按字节计算
minRatio: 0.8, // 只有压缩率比这个值小的资源才会被处理
deleteOriginalAssets: false // 是否删除压缩的源文件
})
服务器需要做响应的配置,把以下配置放到server下,记得重启nginx
服务,响应头出现Content-Encoding: gzip
,就配置成功了
#是否启动gzip压缩,on代表启动,off代表开启
gzip on;
#需要压缩的常见静态资源
gzip_types text/plain application/javascript application/x-javascript text/css application/xml text/javascript application/x-httpd-php image/jpeg image/gif image/png;
#由于nginx的压缩发生在浏览器端而微软的ie6很坑爹,会导致压缩后图片看不见所以该选项是禁止ie6发生压缩
gzip_disable "MSIE [1-6].";
#如果文件大于1k就启动压缩
gzip_min_length 1k;
#以16k为单位,按照原始数据的大小以4倍的方式申请内存空间,一般此项不要修改
gzip_buffers 4 16k;
#压缩的等级,数字选择范围是1-9,数字越小压缩的速度越快,消耗cpu就越大
gzip_comp_level 2;
#如果有已经压缩的(.gz)或者提供静态文件服务,可以设置为on。如果不是这样,最好设置为off,因为这会造成额外的i/o开销。
gzip_static on;
11 根据LightHouse面板性能优化提示,优化对应资源
- 相对较大的图片使用webp
- 图像元素没有显式的宽度和高度
- 开启静态资源缓存
- ...
将优化做到这个程度之后呢,已经有很大一部分提升了,现在的Lighthouse
跑分情况如下:
我是没有把全部静态资源开启缓存的,所以跑分还不够高,若开启缓存,我相信跑分会到90左右,再看看优化后的webpack-bundle-analyzer面板
好啦,暂时优化到这么程度吧,虽然还有些能优化的点,但是现在影响不是很大,大问题都处理了,希望能对您有帮助,那就酱吧,下期再见!