webpack中SplitChunks的分割策略

发布于:2025-07-14 ⋅ 阅读:(15) ⋅ 点赞:(0)

分割策略的科学依据

模块类型 分组策略 原因
核心框架 独立chunk (react-vendor) 变更频率低,长期缓存有效
UI组件库 合并为ui-libs 多页面复用,避免重复加载
业务公共模块 拆为commons 中等变更频率,平衡缓存利用率
低频大库 按需加载(如monaco-editor 避免影响首屏

取舍边界

  • 不拆分:小于10KB的库(如axios)→ 合并入业务代码减少请求数

  • 强制拆分:超过100KB的图表库(如echarts)→ 独立chunk避免阻塞渲染

  • 示例

                splitChunks: {
                    chunks: 'all',
                    minSize: 20000,
                    minRemainingSize: 0,
                    minChunks: 1,
                    maxAsyncRequests: 30,
                    maxInitialRequests: 30,
                    enforceSizeThreshold: 50000,
                    cacheGroups: {
                        // 第三方库
                        vendor: {
                            test: /[\\/]node_modules[\\/]/,
                            name(module) {
                                // 获取模块名称,避免所有vendor打包在一起
                                const packageName = module.context.match(/[\\/]node_modules[\\/](.*?)([\\/]|$)/)[1];
                                return `npm.${packageName.replace('@', '')}`;
                            },
                            priority: 10,
                            reuseExistingChunk: true
                        },
                        // 公共模块
                        common: {
                            minChunks: 2,
                            priority: -20,
                            reuseExistingChunk: true,
                            name: 'common'
                        }
                    }
                }

配置项详解:

1. chunks: 'all'
  • 作用:指定优化范围

  • 选项

    • 'initial':只优化初始 chunk(入口文件)

    • 'async':只优化异步 chunk(动态导入)

    • 'all':优化所有类型 chunk

  • 效果:同时优化初始 chunk 和异步加载 chunk,最大化代码复用

2. minSize: 20000(≈19.5KB)
  • 作用:生成新 chunk 的最小体积阈值

  • 原理:只有模块体积 超过 20KB 才会被考虑拆分

  • 目的:避免生成过多小文件导致 HTTP 请求过多

3. minRemainingSize: 0
  • 作用:拆分后剩余代码块的最小体积

  • 特殊值0 表示不限制

  • 场景:当配合 maxSize 使用时才有意义(此配置未设置 maxSize)

4. minChunks: 1
  • 作用:模块被引用的最小次数

  • 效果:只要被引用 1 次就可能被拆分(实际由 cacheGroups 控制)

  • 注意:此值为全局默认,会被 cacheGroups 覆盖

5. maxAsyncRequests: 30
  • 作用:异步加载时最大并行请求数

  • 效果:按需加载的 chunk 数量不超过 30 个

  • 目的:防止浏览器并行请求过多(HTTP/1.1 下尤为重要)

6. maxInitialRequests: 30
  • 作用:入口点最大并行请求数

  • 效果:初始加载的 chunk 不超过 30 个

  • 重要性:直接影响首屏加载性能

7. enforceSizeThreshold: 50000(≈48.8KB)
  • 作用:强制执行拆分的体积阈值

  • 规则:当 chunk 体积超过 50KB 时,忽略其他限制(minSize/maxRequests)强制拆分

  • 目的:防止超大文件影响加载性能


缓存组策略 (cacheGroups)

🔧 vendor 组(第三方库)

javascript

复制

下载

vendor: {
  test: /[\\/]node_modules[\\/]/,   // 匹配 node_modules 路径
  name(module) {                    // 动态命名函数
    const packageName = module.context.match(
      /[\\/]node_modules[\\/](.*?)([\\/]|$)/
    )[1];
    return `npm.${packageName.replace('@', '')}`; // 输出 npm.包名
  },
  priority: 10,                     // 高优先级
  reuseExistingChunk: true           // 重用现有 chunk
}
  • 创新点name() 函数实现 按包名精细化拆分

    • 传统方案:所有 node_modules 打包成单个 vendor.js(约 1-2MB)

    • 此方案:每个 npm 包独立拆分(如 npm.react-dom.js

  • 优势

    1. 精准缓存:修改某个库时,只有对应 chunk 失效

    2. 并行加载:浏览器可并行下载多个小文件

    3. 依赖清晰:通过文件名直接识别第三方依赖

  • 示例

    • import 'lodash' → 生成 npm.lodash.js

    • import '@babel/runtime' → 生成 npm.babel.runtime.js

🔧 common 组(公共模块)

javascript

复制

下载

common: {
  minChunks: 2,       // 至少被 2 个 chunk 引用
  priority: -20,      // 低优先级(低于 vendor)
  reuseExistingChunk: true, // 重用现有 chunk
  name: 'common'      // 固定名称
}
  • 作用:提取被多页面复用的模块

  • 典型场景

    • 公共工具函数

    • 通用组件(如 Button/Modal)

    • 业务基础配置

  • 优先级逻辑

    1. 先匹配 vendor 组(优先级 10)

    2. 不满足 vendor 的再匹配 common 组(优先级 -20)


网站公告

今日签到

点亮在社区的每一天
去签到