打包优化
现象
前段时间开发的时候遇到客户反馈的一个问题
界面无法打开,显示白屏,控制台无报错
经过我们在开发环境,测试环境反复测试都没复现出客户的问题,然后我们又不停的在生产环境上找问题,也没复现出来
最后我们派了个同事到用户现场去,了解具体情况
原因
经过同事了解发现,客户的电脑带宽只有5M换算下来网速在400kb/s
心理立马万马奔腾 现在还有5M带宽,第一反应领导找客户沟通升级带宽
此路基本行不通,客户属于专网专线的带宽到客户那边分的每台电脑只有那么大的带宽了,不可能给每个人的电脑都去增加带宽,只能先保证几台重要的岗位增加带宽
经过领导们和客户的沟通,最终是,保证功能完好的情况下可以牺牲用户体验,
听到这话,心理又是万马奔腾
这,沟不沟通,不都一样么
现在只能硬着头皮弄了
先来看一下我们最初打包后的文件大小,因为项目中既有cesium.js
的3D效果还有mapbox
的2D效果的地图中间有用了turf
这个处理地理空间数据的工具类所以打包后项目非常大
打包后控制台输出文件大小
打包后项目包大小
居然116MB,怪不得打不开呢
在浏览器中查看请求文件大小
居然有个文件5M,🤯🤯🤯打包后116M 这在5M带宽中 怪不得用户连界面都打不开呢!
开始优化
于是开始了漫长的优化之路
删除打包后的console
内容
安装依赖
npm install uglifyjs-webpack-plugin -D
导入依赖
const UglifyJsPlugin = require("uglifyjs-webpack-plugin")
配置依赖
new UglifyJsPlugin({
uglifyOptions: {
output: {
comments: false
},
compress: {
warnings: false,
drop_console: true,
pure_funcs: ["console.log"] // 移除console
}
},
sourceMap: false,
parallel: true
})
打包后发现这一步杯水车薪,基本上没有左右
压缩成gzip
安装依赖
npm install compression-webpack-plugin -D
导入依赖
const CompressionWebpackPlugin = require('compression-webpack-plugin')
使用依赖
config.plugins.push(new CompressionWebpackPlugin({
algorithm: 'gzip', // 压缩算法
threshold: 10240,// 只处理大于 10KB 的文件
minRatio: 0.6,// 只有压缩率小于 0.6 的文件才会被处理
deleteOriginalAssets: false, // 压缩后删除原始资源文件
}))
于是马上部署了上去,然后在浏览器一看,
晴天霹雳,居然打不开最后通过一顿查找发现需要在nginx上加一个配置
gzip_static on; #开启静态资源压缩
打包后部署上去发现效果显著
5MB的文件立马变成了1.3MB
但此时打包非常慢,基本需要一两个小时才能打出一个包,这就需要一台电脑专门打包了,但公司的电脑基本上都是一人一台,没有多余的电脑,那怎么办呢?
还有没有别的办法呢?
这是恰巧这是看到
有说nginx nginx也可以开启压缩于是试了一下
gzip on; #开启Gzip
gzip_buffers 12 8k; #number:指定Nginx服务器需要向服务器申请的缓存空间的个敿size:指定每个缓存空间的大 ?
gzip_comp_level 4; #压缩级别 ?9,数字越大压缩的越好,时间也越长
gzip_http_version 1.1; #对使用http? ?.0 ?1的请求进行压 ?
gzip_min_length 1k; #不压缩临界值,大于1K的才压缩,一般不用改
gzip_types text/plain application/x-javascript application/javascript text/css application/xml image/jpeg image/gif image/png image/jpg; #进行压缩的文件类 ?
gzip_vary on; #用于设置是否在使用gzip功能时发送带朿vary:Accept-Encoding" 头域的响应头部,该头域的主要功能时要告诉客户端数据已经在服务器进行了压缩,默认设置为off
一看效果基本一致,果断使用
使用上面nginx配置的时候要注意在最开头的http
中配置了就会给所有项目开启压缩
提取公共依赖
通过在网上不停的找,最后又找到了一个方法提取公共依赖的方案
通过下面的这个分析工具我们可以很清楚的看出来哪些插件被多次使用并多次打包到文件中
此时就能分析出那些包需要提取成公共依赖
安装依赖
npm install webpack-bundle-analyzer
导入依赖
const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin
使用依赖
new BundleAnalyzerPlugin()
提取公共依赖
config.optimization.runtimeChunk(false).splitChunks({
chunks: "async",
minSize: 0,
cacheGroups: {
mapbox: {
name: "chunk-mapbox",
priority: 100,
test: /(mapbox-gl(.*))/
},
echarts: {
name: "chunk-echarts",
priority: 80,
test: /(echarts(.*))/
},
pdfjs: {
name: "chunk-pdfjs",
priority: 20,
test: /(pdfjs-dist(.*))/
},
antDesignVue: {//把antDesignVue从chunk-vendors.js提取出来。当然我们也可以把mixins,vue.min.js等等也按照类似配置提取出来
name: 'chunk-ant-design-vue',
test: /[\\/]node_modules[\\/]ant-design-vue[\\/]/,
chunks: 'initial',
priority: 110,
reuseExistingChunk: true,
enforce: true
},
vendor: {
name: "vendor",
test: /[\\/]node_modules[\\/]/,
chunks: "all",
priority: 10
}
}
});
通过一次次分析,
最终提取了mapbox-gl
、echarts
、pdfjs-dist
、ant-design-vue
然后将剩余的包打到vendor
文件中
打包分析图-提取公共依赖前
打包分析图-提取公共依赖后
打包后控制台输出文件大小
打包后项目包大小
在浏览器中查看请求文件大小
这个优化并不能优化我们首屏打开的速度,
但是他能很好的优化我们切换路由的时候页面打开的速度,
因为我们在开发的时候就已经通过路由分包了,
各个组件有都是按需引入,
这就会造成打包的时候有些组件被重复打包到各个分包中去
这个提取公共包,
只能按照自己的项目一点一点的去,
提取打包反复的看,
不然就可能造成,
本来一个很小的文件,
提取后会造成源文件体积变大(我在这个过程中就遇到了)
至此本次优化全部完成
总结
本次优化最终实现将项目包的大小由116MB降到了21.6MB,优化率达到了80%以上,
可以说是一次非常成功的优化了,
让一个大型项目能在只有5MB带宽的网络中能顺利使用起来。