我排查了一下午,发现项目打包体积翻倍的元凶是它

摘要:Vite 产物 JS 堆到近 2MB,我以为是 UI 库太大。打开 rollup-plugin-visualizer 的 Treemap 一看——最大色块居然是 mammoth(docx 预览)。这篇文章讲怎么看这张「体积地图」,以及我在真实项目里怎么定位、怎么拆。

我负责的H5(React 18 + Vite),生产构建后 dist/prod 里 JS 合计大概 2MB。首屏倒不至于卡死——路由和 vendor 都拆过了——但一打开体积报告,心里还是咯噔一下:这堆东西里,到底谁在吃体积?

翻 package.json 没用。antd-mobile、react-dom、axios……名字都眼熟,分不出谁最大。

直到跑了一次 rollup-plugin-visualizer,Treemap 上最大的那一块标着 vendor-mammoth,将近 490KB。

协议预览页为了本地转 docx,动态 import('mammoth') 了一下。功能是低频的,体积却悄悄躺成了全项目第一名。

rollup-plugin-visualizer 干的事很简单:

你 vite build 一次,它给你吐一张 stats.html。 打开之后,每个依赖/模块是一块色块,色块越大 = 占的体积越大。

可以把它想成小区平面图:谁占的房间大,一眼就看出来。不用猜,不用一个个 import 试。

Vite 底层用 Rollup 打生产包,所以这个插件对 Vite 项目直接可用。

我项目里的写法(只在 build 时启用,本地 dev 不跑):

浏览器会弹出 stats.html。没有自动打开就自己双击项目根目录下的这个文件。

不想每次正式构建都生成报告?用环境变量开关更稳(见文末踩坑):

新手别一上来切 Network,线多容易晕。先看 Treemap:找最大的几块 → 点进去看包名 → 再决定动不动刀。

打开报告后,顶部还有 Rendered / Gzip / Brotli 三个单选:

我排查时先用 Rendered 锁定最大色块,再用 Gzip 确认它是不是「吓人大、压缩后也大」。

这是我项目里真实的 Treemap(右下粉色大块就是 mammoth,旁边紫色是它拖进来的 bluebird):

项目背景: H5,React + Vite,UI 用 antd-mobile,日期用 dayjs(没有 moment)。业务里有一个「协议 / 文档预览」页,本地 .docx 要转成 HTML 展示。

生产产物里,最大的几个 JS 大致是这样(本机 dist/prod,未 gzip):

图上还能看到:mammoth 旁边紧挨着 bluebird、jszip、underscore 一类依赖——不是业务直接装的,是 mammoth 自己拖进来的。所以 Treemap 里「一大坨粉色 + 紫色」,本质上是同一条 docx 预览链路。

mammoth 单独 gzip 后大约 127 KB,仍然不小。antd-mobile(中间褐色那些 Picker / Tabs / Button)全家桶加起来也不小,但我原本以为体积问题全怪 UI 库——图一出来,结论就反了。

路由也是 React.lazy 懒加载的。所以:

「拆包 / 懒加载」解决的是何时下载,不是「这个库变小了」。两件事别混。

精确到「首屏从 x 秒到 y 秒」取决于网络和页面,这里不强行编造;**「最大色块从瞎猜变成可指认」**这件事本身,已经值回排查那一下午。

不同项目元凶不一样。Treemap 里如果冒出下面这些,可以直接按套路砍:

来源:稀土掘金 原文