构建产物体积排查:从 2MB 降到 300KB
页面首屏慢,很多时候不是接口慢,而是首屏要下载的 JS 太大。这篇记一下我排查产物体积的固定套路, 以及几种优化手段的实际收益。
第一步:先看清体积到底花在哪
不要凭感觉猜“肯定是某个组件库太大”。构建工具基本都能输出体积报告,先拿到数据再动手:
# Vite:生成可视化体积报告
npx vite build --mode production
# 只看产物的原始与 gzip 体积
ls -lh dist/assets/*.js | sort -k5 -h
我的习惯是先看 gzip 后的体积——用户实际下载的是它。一个 2MB 的原始文件 gzip 后可能只有 500KB, 优先级和“原始体积最大”的那个模块往往不是同一个。
第二步:区分“真大”和“重复打包”
体积报告里常见两类问题,处理方式完全不同:
- 单个依赖确实大:比如图表库、富文本编辑器。这种要么按需引入,要么把它挪出首屏(动态 import)。
- 同一个依赖被打进多个 chunk:多见于多入口或路由懒加载切分不当。特征是同一个包名在报告里出现多次。
第二个问题特别容易被忽略:它不会让报告里的“最大模块”看起来异常,但总下载量会明显偏大。
第三步:几种手段与实测收益
按我自己的经验,收益从高到低大致是:
- 把首屏用不到的东西改成动态 import。典型是“只在弹窗里用”的重组件。 我这次把一个编辑器组件拆出去,首屏直接少了 400KB 左右。
- 补齐按需引入。组件库整包引入是最常见的大头,改成按需后通常能砍掉一半以上。
- 合并重复依赖。用包管理器提供的分析命令找出同一包的多个版本,尽量收敛成一个。
-
检查是否有源码被整体打包。比如误把整个
src目录当资源引入, 或者把大段 JSON 当常量打进代码。
几个容易白忙一场的点
- 为了体积牺牲可读性。把两个不相干的模块硬塞进一个文件,省下的那点体积不值得。
- 只看原始体积不看 gzip。重复字符串多的文件 gzip 压缩率很高,优化它收益有限。
- 优化完不复测。动态 import 会让请求数变多,在网络差的场景不一定更快, 改完最好在真实网络下再跑一遍。
最后提醒一句:体积优化要设一个“够用”的目标(比如首屏 JS gzip 控制在 300KB 以内), 达到就停手。把它当成日常体检,而不是一次性的攻坚战。
← 返回首页