Webpack4.0打包分离chunk优化

4,835 阅读2分钟

Webpack官方文档这么说:代码分离是webpack中最引人注目的特性之一。此特性能够把代码分离到不同的bundle中,然后可以按需加载或并行加载这些文件。代码分离可以用于获取更小的bundle,以及控制资源加载优先级,如果使用合理,会极大影响加载时间。

要想做chunk分离优化,首先要知道当前哪些chunk包体积较大,才能明确方向。以vue-cli3.0为例,开始Webpack打包分离chunk优化之旅。


vue-cli3默认配置build,打包结果如下:

Webpack4.0升级以后,CommonsChunkPlugin被删除,被optimization.splitChunks和optimization.runtimeChunk配置化所代替。

Webpack自动分离chunk包基于以下几个条件:

  • 来自公共模块node_modules
  • 压缩前包体积大于30kb(默认)
  • 按需加载并行请求chunk包数量不超过5个(默认)
  • 首屏初始化加载并行请求chunk包数量不超过3个(默认)

SplitChunksPlugin默认配置:

optimization: {
        minimize: false,
        splitChunks: {
            chunks: 'all',//表示显示块的范围,有三个可选值:initial(初始块)、async(按需加载块)、all(全部块)(default=all);
            name: true,//拆分出来块的名字(Chunk Names),默认由块名和hash值自动生成;
            minChunks: 1,//在分割之前模块的被引用次数(default=1)
            minSize: 30000,//代码块的最小尺寸(default=30000)
            maxAsyncRequests: 5,//按需加载最大并行请求数量(default=5)
            maxInitialRequests: 3,//一个入口的最大并行请求数量(default=3)
            automaticNameDelimiter: '~',
            cacheGroups: {//可以继承/覆盖上面 splitChunks 中所有的参数值
                vendors: {
                    name: "vendors",
                    chunks: "all",
                    test: /node_modules\//,//表示要过滤 modules,默认为所有的 modules,可匹配模块路径或 chunk 名字,当匹配的是 chunk 名字的时候,其里面的所有 modules 都会选中;
                    priority: 10,//表示抽取权重,数字越大表示优先级越高。因为一个 module 可能会满足多个 cacheGroups 的条件,那么抽取到哪个就由权重最高的说了算;
                    reuseExistingChunk: true//表示是否使用已有的 chunk,如果为 true 则表示如果当前的 chunk 包含的模块已经被抽取出去了,那么将不会重新生成新的。
                },
                commons: {
                    name: "commons",
                    chunks: "initial",
                    minChunks: 2
                }
            }
        },
        runtimeChunk: {
            name: "manifest"
        }
    }

但是,默认配置build结束,公共vendor包体积明显太大,影响加载性能。尽量控制每个chunk包体积不大于30kb。

下面工作就是就是继续分离vendors包。

优化后的配置:

optimization: {
      splitChunks: {
        chunks: "all",
        minSize: 30000,
        maxAsyncRequests: 5,
        maxInitialRequests: 5,
        cacheGroups: {
          vue: {
            test: /[\\/]node_modules[\\/](vue)[\\/]/,
            name: "vue",
            priority: 2
          },
          router: {
            test: /[\\/]node_modules[\\/](vue-router)[\\/]/,
            name: "vue-router",
            priority: 2
          },
          vendors: {
            test: /[\\/]node_modules[\\/]/,
            name: "vendors",
            priority: 1,
            reuseExistingChunk: true
          }
        }
      },
      runtimeChunk: {
        name: "manifest"
      }
    }

项目重新build,结果如下:

总结:本次只是对splitChunks优化分chunk打包策略的实践,大家具体如何制定策略还得根据实际业务来。