再战前端性能优化之代码分割,bundle包减少了26% - zptime/blog GitHub Wiki

主要介绍代码分割(Code Splitting),使用SplitChunksPlugin插件,将第三方库或者公共基础组件进行单独打包,合理利用缓存,进行按需或者并行加载,提高首屏加载速度

前言

系列文章:

本篇接着之前的配置,优化同一个系统,还是从细节优化入手的,主要介绍代码分割。

代码分割(Code Splitting)是 webpack 最强大的功能之一,可以将代码拆分为多个包(bundle),然后对这些包进行按需或者并行加载,可以提高首屏加载速度。

我使用的 webpack 版本为 v4.28.4,代码分割使用的插件为 SplitChunksPlugin,这个插件的使用真的很灵活,要找到最佳实践方式真的是很难的呀,需要自己慢慢摸索体会

温馨提示:以下bundle包大小均为未压缩前的大小,生产环境的代码通过gzip后,会减少约75%

优化前分析

具体操作可查看第一篇文章中的 项目打包构建 -> Analyzer 分析

由下图可以分析出:入口文件包还是很大的,而打包提示建议的大小是 244KB,优化工作任重而道远呀

  • 总包大小为 6.57MB
  • 入口文件大小为 3.16MB:main.js(3.1MB) + main.css(57.3KB) + runtime.js(4.41KB)
  • main.js 大小为 3.1MB:main_modules(1.24MB) + UI(871.91KB)+ node_modules(906.61KB)

图示展示

第一次优化

主要是将第三方库或者公共基础组件单独打包,这些变化比较少,单独打包利于缓存。

// 修改webpack.config.js
module.exports = {
  optimization: {
    namedModules: true,
    namedChunks: true,
    runtimeChunk: {
      name: "runtime",
    },
    splitChunks: {
      chunks: "all", // all,async 和 initial
      minSize: 20000, // 生成 chunk 的最小体积
      minChunks: 1, // 拆分前必须共享模块的最小 chunks 数
      maxAsyncRequests: 5, // 按需加载时的最大并行请求数
      maxInitialRequests: Infinity, // 入口点的最大并行请求数
      automaticNameDelimiter: "~", // 指定用于生成名称的分隔符
      cacheGroups: {
        default: false,
        vendors: {
          name: "chunk-vendor",
          chunks: "all",
          minChunks: 2,
          test: /[\\/]node_modules[\\/]/,
          // test: /[\\/]node_modules[\\/]|vendor[\\/]analytics_provider|vendor[\\/]other_lib/
          priority: -20,
        },
        commons: {
          name: `chunk-common`,
          chunks: "all",
          minChunks: 2,
          // priority的值必须比vendors中的大,才能提取出来
          priority: -10,
        },
      },
    },
  },
};

分析结果:总包大小为 4.79MB(压缩后 1.16MB),减少了 1.78MB(1823KB);入口文件还是 3.16MB,没变;chunk-common726KB

图示展示

图示展示

第二次优化

主要是将 ant design vue 单独打包出来

// 修改webpack.config.js
module.exports = {
  optimization: {
    splitChunks: {
      cacheGroups: {
        // 省略其他......
        ant_design: {
          chunks: "all",
          name: `ant_design`,
          test: /[\\/]ant-design-vue[\\/]/,
          priority: 0,
        },
      },
    },
  },
};

分析结果:虽然入口文件增加了 72 KB,但是 main.js 分成了两个文件,可以并行加载,会提高首屏速度

  • 总包大小为 4.85MB,相比第一次优化,增加了0.06MB(61KB)
  • 入口文件为 3.23MB,增加0.07MB(72KB):main.js(1.86MB,压缩后 533KB),ant_design.js(1.31MB,压缩后 276KB)

图示展示

图示展示

第三次优化

ant design icon 单独打包出来

// 修改webpack.config.js
module.exports = {
  optimization: {
    splitChunks: {
      cacheGroups: {
        // 省略其他......
        ant_design_icons: {
          chunks: "all",
          name: `ant_design_icon`,
          test: /[\\/]@ant-design[\\/]/,
          priority: 0,
        },
      },
    },
  },
};

分析结果:总包大小仍然为 4.85MB,入口文件为 3.23MB,都没变;所以没必要单独提取出来了,反而增加请求数,最终还是以第二次的打包配置为准

图示展示

图示展示

参考文档: