前言

最近发现公司前端我的项目打包后生成的单个文件都超过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中,

将我的项目文件的公共局部进行拆包,如src/components和src/views文件夹

总结

援用