Webpack分包策略

2021-07-16  本文已影响0人  杭州程序员小陈

在 webpack 打包过程中,经常出现 vendor.js, app.js 单个文件较大的情况,这偏偏又是网页最先加载的文件,这就会使得加载时间过长,从而使得白屏时间过长,影响用户体验。所以我们需要有合理的分包策略。

CommonsChunkPlugin

在 Webapck4.x 版本之前,我们都是使用 CommonsChunkPlugin 去做分离

···<pre data-language="javascript" id="L4z5I" class="ne-codeblock" style="border: 1px solid #e8e8e8; border-radius: 2px; background: #f9f9f9; padding: 16px; font-size: 13px; color: #595959">plugins: [
  new webpack.optimize.CommonsChunkPlugin({
    name: 'vendor',
    minChunks: function (module, count) {
      return (
        module.resource &&
        /\.js$/.test(module.resource) &&
        module.resource.indexOf(path.join(__dirname, './node_modules')) === 0
      )
    },
  }),
  new webpack.optimize.CommonsChunkPlugin({
    name: 'common',
    chunks: 'initial',
    minChunks: 2,
  }),
]</pre>

我们把以下文件单独抽离出来打包

optimization.splitChunks

webpack 4 最大的改动就是废除了 CommonsChunkPlugin 引入了 optimization.splitChunks。如果你的 mode 是 production,那么 webpack4 就会自动开启 Code Splitting。

它内置的代码分割策略是这样的:

虽然在 webpack4 会自动开启 Code Splitting,但是随着项目工程的最大,这往往不能满足我们的需求,我们需要再进行个性化的优化。

应用实例

我们先找到一个优化空间较大的项目来进行操作。这是一个后台管理系统项目,大部分内容由 3-4 个前端开发,平时开发周期较短,且大部分人没有优化意识,只是写好业务代码完成需求,日子一长,造成打包出来的文件较大,大大影响性能。

我们先用 webpack-bundle-analyzer 分析打包后的模块依赖及文件大小,确定优化的方向在哪。

![tps:https://img.haomeiwen.com/i6334858/ef229e41ef621599.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)

然后我们再看下打包出来的 js 文件

![image](https://img.haomeiwen.com/i6334858/bb256a2faa48ca7b.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)

看到这两张图的时候,我内心是崩溃的,槽点如下

吐槽完之后我们就要开始做正事了。正是因为有这么多槽点,我们才更好用来验证我们优化方法的可行性。

抽离 echart 和 iview

由上面分析可知,echart 和 iview 文件太大,此时我们就用到 webpack4 的 optimization.splitChunks 进行代码分割了,把他们单独抽离打包成文件。(为了更好地呈现优化效果,我们先把 xlsx.js 去掉)

vue.config.js 修改如下:

<pre data-language="javascript" id="uP8eu" class="ne-codeblock" style="border: 1px solid #e8e8e8; border-radius: 2px; background: #f9f9f9; padding: 16px; font-size: 13px; color: #595959">chainWebpack: config => {
    config.optimization.splitChunks({
      chunks: 'all',
      cacheGroups: {
        vendors: {
          name: 'chunk-vendors',
          test: /[\\/]node_modules[\\/]/,
          priority: 10,
          chunks: 'initial'
        },
        iview: {
          name: 'chunk-iview',
          priority: 20,
          test: /[\\/]node_modules[\\/]_?iview(.*)/
        },
        echarts: {
          name: 'chunk-echarts',
          priority: 20,
          test: /[\\/]node_modules[\\/]_?echarts(.*)/
        },
        commons: {
          name: 'chunk-commons',
          minChunks: 2,
          priority: 5,
          chunks: 'initial',
          reuseExistingChunk: true
        }
      }
    })
  },
 </pre>

此时我们再用 webpack-bundle-analyzer 分析一下

![image](https://img.haomeiwen.com/i6334858/c62a3418b9d236a3.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)

打包出来的 js 文件

image

从这里可以看出我们已经成功把 echart 和 iview 单独抽离出来了,同时 vendor.js 也相应地减小了体积。此外,我们还可以继续抽离其他更多的第三方模块。

CDN 方式

虽然第三方模块是单独抽离出来了,但是在首页或者相应路由加载时还是要加载这样一个几百 kb 的文件,还是不利于性能优化的。这时,我们可以用 CDN 的方式引入这样插件或者 UI 组件库。

  1. index.html 引入相应 cdn 链接
<head>  <link rel="stylesheet" href="https://cdn.bootcdn.net/ajax/libs/iview/3.5.4/styles/iview.css" /></head><body>  <div id="app"></div>  <script src="https://cdn.bootcss.com/vue/2.6.8/vue.min.js"></script>  <script src="https://cdn.bootcdn.net/ajax/libs/iview/3.5.4/iview.min.js"></script>  <script src="https://cdn.bootcdn.net/ajax/libs/xlsx/0.16.8/xlsx.mini.min.js"></script>  <script src="https://cdn.bootcdn.net/ajax/libs/xlsx/0.16.8/cpexcel.min.js"></script></body>
  1. vue.config.js 配置 externals
configureWebpack: (config) => {  config.externals = {    vue: 'Vue',    xlsx: 'XLSX',    iview: 'iView',    iView: 'ViewUI',  }}
  1. 删除之前的引入方式并卸载相应 npm 依赖包
npm uninstall vue iview echarts xlsx --save

此时我们在来看一下打包后的情况

![image](https://img.haomeiwen.com/i6334858/21d7230400eefb3b.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)

打包出来的 js 文件

![image](https://img.haomeiwen.com/i6334858/3a1a85942caabe09.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)

well done ! 这时基本没有打包出大文件了,首页加载需要的 vendor.js 也只有几十 kb,而且我们还可以进一步优化,就是把 vue 全家桶的一些模块再通过 cdn 的方法引入,比如 vue-router,vuex,axios 等。这时页面特别是首页加载的性能就得到大大地优化了。

上一篇下一篇

猜你喜欢

热点阅读