乐趣区

关于javascript:前端打包优化

前言

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

总结

援用

退出移动版