第3章:打包产物分析 — 用 Webpack Bundle Analyzer 可视化分析

说实话,很多前端同学对打包体积的认知,还停留在「看个总大小」的阶段。

项目一大了,dist 目录里一堆文件,哪个是哪个?哪个模块占了 500KB?哪个库其实根本没用上?

嗯,这时候就需要一个趁手的工具了。我个人最常用的,就是 Webpack Bundle Analyzer

3.1 为什么需要可视化分析?

你想想看,光看控制台输出的构建日志,你能看出什么?

  • 总大小:2.3 MB
  • 构建时间:12.8s

没了。就这俩数字,根本没法指导优化。

但如果你能看到一张交互式饼图,每个模块的大小、依赖关系一目了然——

  • 哦,原来 moment.js 占了 600KB
  • 哦,原来 lodash 被全量引入了
  • 哦,原来某个业务组件里偷偷 import 了一张大图

这时候你才知道该从哪里下手。我在项目中遇到过好几次,团队里有人抱怨「打包太慢、体积太大」,结果一分析,发现是某个同事把整个 UI 库都 import 了。你说冤不冤?

3.2 安装与配置

安装很简单,一行命令搞定:

npm install --save-dev webpack-bundle-analyzer

然后在 webpack 配置里引入插件:

const { BundleAnalyzerPlugin } = require('webpack-bundle-analyzer');

module.exports = {
  plugins: [
    new BundleAnalyzerPlugin({
      // 可选配置
      analyzerMode: 'static',   // 生成静态 HTML 报告
      reportFilename: 'report.html',
      openAnalyzer: false,       // 不自动打开浏览器
    })
  ]
};

我个人习惯在开发环境用 server 模式,构建完自动弹出交互页面;生产环境用 static 模式,生成一份报告存着,方便对比。

小技巧: 可以配合环境变量来控制是否启用分析器。比如只在 ANALYZE=true 时才加载插件,避免每次构建都跑一遍。

3.3 读懂分析报告

跑完构建,你会看到这样一个界面:

左侧是文件树,右侧是可视化饼图。每个方块代表一个模块,方块越大,体积越大。

颜色越深,说明这个模块的依赖越复杂。

我一般会重点关注几个地方:

  • 重复的库:同一个库出现在多个 chunk 里,比如 react 被打了两次
  • 过大的第三方库:比如 moment.jslodashecharts
  • 意外的依赖:比如某个工具函数里引入了整个 axios
  • 未使用的代码:Tree Shaking 没生效的模块
注意: 饼图里显示的「Parsed size」是经过压缩后的估算值,不是最终 gzip 后的体积。实际线上体积会更小,但分析时看这个就够了。

3.4 实战案例:一次真实的优化

我记得有一次,一个后台管理系统打包出来 4.2 MB。老板说「这加载也太慢了」。我打开分析报告一看——

模块 体积 (KB) 占比
moment.js 612 14.5%
lodash 524 12.4%
echarts 890 21.1%
业务代码 ~2.1 MB 50%

问题很明显:

  • moment.js 只用了日期格式化,完全可以换成 dayjs(2KB)
  • lodash 只用了 _.get_.debounce,改成按需引入
  • echarts 只用了折线图和柱状图,换成按需加载

优化后,打包体积从 4.2 MB 降到了 1.8 MB。老板说「嗯,这次可以了」。

核心思路: 先分析,再优化。不要凭感觉去删代码,让数据告诉你该删什么。

3.5 进阶用法:对比分析

光看一次的报告还不够。我建议每次发版前,都生成一份报告存档。

这样你可以对比两个版本之间的变化:

  • 这次新增了哪个库?
  • 哪个模块体积变大了?
  • Tree Shaking 有没有生效?

Webpack Bundle Analyzer 支持 --mode static 生成 JSON 文件,然后用 diff 工具对比。不过说实话,我更喜欢手动截图保存,因为更直观。

小技巧: 可以在 CI/CD 流程里加入体积检查。如果某个 PR 导致打包体积增长超过 10%,就自动告警。这样能避免「不知不觉变大了」的情况。

3.6 常见问题与避坑

用这个工具的时候,有几个坑我踩过:

  • 报告打不开:检查一下 reportFilename 路径是否正确,有时候是相对路径的问题
  • 体积显示为 0:可能是某些模块被标记为 external,或者被 CDN 加载了
  • 分析太慢:大型项目第一次分析可能会卡几秒,耐心等一等

我曾经有一次,分析报告里显示某个模块 0KB,我还以为出 bug 了。后来发现是那个模块被 webpack 的 externals 配置排除了,根本没打进包里。嗯,虚惊一场。

3.7 总结

Webpack Bundle Analyzer 是我工具箱里最常用的工具之一。它不复杂,但能帮你快速定位问题。

说白了,优化打包体积的第一步,就是「看清楚」。

下一章,我会讲怎么用 Tree Shaking 干掉那些没用的代码。到时候你会发现,很多「优化技巧」其实都是建立在分析报告之上的。

一句话记住: 先分析,再优化。没有数据支撑的优化,都是瞎忙活。