前言
最近发现公司前端我的项目打包后生成的单个文件都超过4Mb了,导致页面关上的时候十分慢,于是着手优化打包,指标是实现单个文件大小低于1Mb。
筹备
在优化之前咱们先提出两个优化思路,如下所示:
1、应用CDN引入包文件
2、应用npm引入的第三方包文件进行拆包
3、将我的项目文件的公共局部进行拆包,如src/components和src/views文件夹
有了思路之后,接下来咱们就开干。留神:上面我是用vue我的项目做为演示。
应用CDN引入包文件
实用的场景:
公共的框架或者库独自引入,避免nodejs打包引入,如:vue.js、vuex、vue-router和elementui。
实现:
咱们能够应用第三方CDN库复制链接放入public/index.html文件中,如下所示 :
尽管咱们引入了,然而咱们还要配置webpack不要把nodejs引入的包进行打包。
批改vue.config.js文件,如下所示:
configureWebpack: { name: name, externals: { // 包名: '引入名' vue: 'Vue', vuex: 'Vuex', 'vue-router': 'VueRouter', 'element-ui': 'Element', moment: 'moment', dayjs: 'dayjs', axios: 'axios', clipboard: 'ClipboardJS', echarts: 'echarts', html2canvas: 'html2canvas', 'js-beautify': 'beautifier', 'js-cookie': 'Cookies', lodash: '_', qrcode: 'QRCode', screenfull: 'screenfull', 'vue-clipboard2': 'VueClipboard', 'vue-i18n': 'VueI18n' }
下面externals中key是包名,value是引入名,大家依照这个参考设置就好。这样就实现了第1步的操作。
应用npm引入的第三方包文件进行拆包
接下来咱们剖析一下前端我的项目打包后的报告,剖析文件大小状况,依据这个报告咱们来判断是否要分包,如下所示。
批改vue.config.js文件
const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin configureWebpack: { name: name, externals: { // 包名: '引入名' vue: 'Vue', vuex: 'Vuex', 'vue-router': 'VueRouter', 'element-ui': 'Element', moment: 'moment', dayjs: 'dayjs', axios: 'axios', clipboard: 'ClipboardJS', echarts: 'echarts', html2canvas: 'html2canvas', 'js-beautify': 'beautifier', 'js-cookie': 'Cookies', lodash: '_', qrcode: 'QRCode', screenfull: 'screenfull', 'vue-clipboard2': 'VueClipboard', 'vue-i18n': 'VueI18n' }, resolve: { alias: { '@': resolve('src'), '@@': resolve('src/x7') } } plugins: [ new BundleAnalyzerPlugin() ]}
批改package.json文件
"scripts": { "build:report": "vue-cli-service build --report"},
运行命令:
pnpm run build:report
如下所示,以后文件打包状况:
通过剖析能够晓得,chunk文件和app文件比拟大,咱们再看下图表看看能不能把外面大的包拆分进去,如下所示:
通过图表能够看进去,这些包都能够拆分进去,于是咱们改下vue.config.js把下面的包全副拆分进去,如下所示:
config.optimization.splitChunks({ chunks: 'all', minSize: 20000, maxSize: 0, minChunks: 1, maxAsyncRequests: 30, maxInitialRequests: 30, automaticNameDelimiter: '\~', enforceSizeThreshold: 50000, cacheGroups: { libs: { name: 'chunk-libs', test: /[\\/]node_modules[\\/]/, priority: 120, chunks: 'initial' // only package third parties that are initially dependent }, corejs: { name: 'chunk-corejs', // split elementUI into a single package priority: 141, // the weight needs to be larger than libs and app or it will be packaged into libs or app test: /[\\/]node_modules[\\/]_?core-js(.*)/ // in order to adapt to cnpm }, graphic: { name: 'chunk-zrender', // split elementUI into a single package priority: 142, // the weight needs to be larger than libs and app or it will be packaged into libs or app test: /[\\/]node_modules[\\/]_?zrender(.*)/ // in order to adapt to cnpm }, viewerjs: { name: 'chunk-viewerjs', // split elementUI into a single package priority: 143, // the weight needs to be larger than libs and app or it will be packaged into libs or app test: /[\\/]node_modules[\\/]_?viewerjs(.*)/ // in order to adapt to cnpm }, hotFormulaParser: { name: 'chunk-hotFormulaParser', // split elementUI into a single package priority: 144, // the weight needs to be larger than libs and app or it will be packaged into libs or app test: /[\\/]node_modules[\\/]_?hot-formula-parser(.*)/ // in order to adapt to cnpm }, elementUI: { name: 'chunk-elementUI', // split elementUI into a single package priority: 130, // the weight needs to be larger than libs and app or it will be packaged into libs or app test: /[\\/]node_modules[\\/]_?element-ui(.*)/ // in order to adapt to cnpm }, einUI: { name: 'chunk-einUI', // split elementUI into a single package priority: 125, // the weight needs to be larger than libs and app or it will be packaged into libs or app test: /[\\/]node_modules[\\/]_?ein-ui(.*)/ // in order to adapt to cnpm }, echarts: { name: 'chunk-echarts', // split elementUI into a single package priority: 122, // the weight needs to be larger than libs and app or it will be packaged into libs or app test: /[\\/]node_modules[\\/]_?echarts(.*)/ // in order to adapt to cnpm }, handsontable: { name: 'chunk-handsontable', // split elementUI into a single package priority: 123, // the weight needs to be larger than libs and app or it will be packaged into libs or app test: /[\\/]node_modules[\\/]_?handsontable(.*)/ // in order to adapt to cnpm }, codemirror: { name: 'chunk-codemirror', test: /[\\/]node_modules[\\/]_?codemirror(.*)/, // in order to adapt to cnpm minChunks: 1, // minimum common number priority: 140, reuseExistingChunk: true } } })
咱们把想要拆分的包都放到cacheGroups中,