webpack4系列之【3. webpack4优化记录】
背景:
运行环境:node v11.2.0 ;webpack 4.27.1
性能检测工具:webpack-bundle-analyzer
优化前视图:
stat: 12.06M (打包之前输入的文件大小)
parsed: 5.51M(打包之后输出的文件大小)
gzipped: 1.68M(开启gzip压缩后的文件大小)
从analyzer视图来看,最大的chunk2.47M,较大的也有700多k,500多k,400k等,从这些大chunk入手,进行优化。
问题:
- 项目体积过大
- 多个工具被打包到一个chunk,导致chunk过大,加载比较费时
- 当前页面不需要用到的工具库同时被加载,性能变差
优化项:
1. cdn引入。
externals排除第三方工具库,不打包进项目中。index.html中,script标签引入这些工具库。
优点:减少项目体积
问题:直接在index.html中引入,同样导致不需要的工具库被加载;如果cdn不稳定,有可能导致项目瘫痪;
2.轻量级工具库替换
moment.js替换为更为轻量的dayjs
3.按需引入
有些工具库,用到的方法,可能只是其中几个,但是却把整个库引了进来,加大项目体积。建议考虑按需引入。
排查中,较大的库有element.ui,echarts,c3,d3。
-- element.ui
element.ui按需引入方案可见官网https://element.eleme.cn/#/zh-CN/component/quickstart。也可以使用插件 babel-plugin-component。
以上两种方式都需要将使用到的组件挨个儿引入。bm-fe项目较大,且用到的组件较多,操作起来代价比较大,所以放弃element.ui按需引入。
-- echarts
最初方案是cdn引入,缺点见【1.cdn引入】,更改方案为:echarts.min.js以及使用的主题js文件存储为静态文件,在需要使用的页面动态插入script标签,引入echarts及对应主题
-- 百度地图api优化
原百度地图api直接在index.htlm中引入,导致任何页面加载时,都将引用该api,造成资源浪费,增加耗时。
解决办法:封装promise,动态插入script标签,引入百度地图api。
弊端:百度地图api(简称:apiKey1)的目的是要执行该api返回的脚本,这段脚本动态向html中插入一个js(简称:apiKey2),这个js才是渲染出百度地图真正依赖的脚本。
但是动态插入script标签引入apiKey1,发现插入成功后,无法直接执行将apiKey2插入到html中(直接在script中引入时,会自动执行apiKey1返回的脚本,即:将apiKey2插入到html中)。
原因暂不明确。
所以最终方案是,直接动态插入script标签,将百度地图apiKey2插入到html中。
=====各位同学知晓原因的或者有更好解决方案的,随时交流,期待中~=======
-- c3,d3
c3 和d3都比较大。
首先处理的是d3,按需引入d3中需要的模块。发现被按需引入的模块单独被打包之外,整个d3又被重复打包。
后来查看c3 package.json以及源码发现,c3把d3整个require进来了,所以,导致d3被重复打包。
解决方案....并没有找到很合适的。
由于引用c3的项目,已经没人用了,于是乎下掉了这个项目...
================以上优化,使用方法详见项目README~=============
4. code split提取公共代码,按需加载
-- 提取 UI框架:/[\\/]node_modules[\\/]element-ui[\\/]/,
-- 提取vue系列基础类库:/[\\/]node_modules[\\/](vu(e((-router)|x)*))/
-- 提取常用工具:/[\\/]node_modules[\\/]((native-api)|(axios)|(qs)|(upload-image))/,
-- 提取较大工具库:/[\\/]node_modules[\\/][c|d]3/,/[\\/]node_modules[\\/]quill/
-- 提取公共代码:/[\\/]src[\\/]components[\\/]pages/
5.其他优化点
-- mini-css-extract-plugin 提取css文件
-- optimize-css-assets-webpack-plugin 压缩css
-- uglifyjs-webpack-plugin 压缩js
-- lodash-webpack-plugin lodash按需引入
-- 等
优化后
stat: 10.06M (打包之前输入的文件大小)
parsed: 4.57M(打包之后输出的文件大小)
gzipped: 1.37M(开启gzip压缩后的文件大小)
-- 由于项目要上传sourcemap,设置 devtool: 'hidden-source-map',hidden-source-map和source-map类似,会把源码上传,因此会对项目体积有所影响。