1-4 扩展Turbopack真的比Vite快10倍吗?
事件背景
Turbopack 在发布时蹭了 Vite 的"快"这个热点——Vite 的名字来自法语,意为"快"。Vercel 发布博文宣称 Turbopack 比 Vite 快 10 倍以上。Vite 作者尤雨溪看到后立即创建了 vite-vs-next-turbo-hmr 仓库进行深入对比分析。
Turbopack 是一个针对 JavaScript 和 TypeScript 进行优化的增量打包工具,由 Webpack 和 Next.js 在 Vercel 用 Rust 语言编写。其性能出色的秘密有两个方面:高度优化的机器代码和低级别的增量计算引擎,使得缓存可以达到单个函数级别——一旦完成一个任务,就不会再次执行相同任务。
基准测试方法
测试使用 Next.js 13 和 Vite 3.2 两个版本,通过两个时间点来度量 HMR 性能:
- 文件修改时间戳:通过独立 Node.js 进程监视文件变化记录
- React 组件重新渲染时间戳:在渲染虚拟 DOM 时记录(不受 React 协调或实际 DOM 更新的影响)
测试分别针对两种不同情况:
- 根(Root)情况:组件导入了 1000 个不同的子组件,并将它们一起渲染
- 叶(Leaf)情况:该组件由根导入,但没有自己的导入或子组件
对比结论
React 服务器组件(RSC)的影响
Next 13 引入了重大架构变化,默认情况下组件都是服务器组件,除非用户通过 "use client" 指令明确选择客户端模式。初始基准测试中,根组件和叶子组件都处于服务器模式时,Next 13 在两种情况下实际上都比较慢,尤其是叶子组件差距很大。当给 Next 根组件添加 "use client" 指令后,Next 的 HMR 显著改善,比 Vite 快约 2 倍。
SWC vs Babel 转换
React HMR 和 JSX 转换不是与构建工具耦合的功能,可以通过 Babel(基于 JavaScript)或 SWC(基于 Rust)来完成。SWC 比 Babel 快得多(单线程 20 倍,多核心 70 倍)。Vite 默认使用 Babel 的原因是安装大小和实用性的权衡——SWC 的 node_modules 有 58MB,而 Vite 本身只有 19MB。
Vite 核心不依赖 Babel,只需将默认的 React 插件替换为 vite-plugin-swc-react-refresh 即可切换到 SWC。切换后的对比数据:
| 场景 | Vite (root) | Vite (leaf) | Next (root) | Next (leaf) |
|---|---|---|---|---|
| 5 次平均 (ms) | 338.2 | 141.8 | 334.6 | 84.4 |
值得注意的是,在根案例中 Next/turbo 相比叶子案例慢了 4 倍,而 Vite 只慢了 2.4 倍,这意味着在更大的组件中 Vite HMR 能更好地扩展。
不同硬件上的性能差异
由于是涉及 Node.js 和原生 Rust 部分的综合基准测试,不同硬件上会存在显著差异。在某些硬件上 Vite 在根案例中更快,在其他情况下则无论是根还是叶都明显更快。
数据造假的质疑
原始 1K 组件的基准测试中存在四舍五入的问题:
- Turbopack 将自己的 15ms 四舍五入为 0.01s
- 将 Vite 的 87ms 定位为 0.09s
- 0.09 / 0.01 = 9 倍,被宣传为"10 倍优势"
- 实际上原始数据只有约 6 倍的优势
极端场景
Turbopack 在总模块超过 30K 时性能优于 Vite,但现实中前端项目很少有这么庞大的模块量——大多数项目的模块量在 20K 以内。Vite 应用程序预打包了依赖项,现实中几乎不可能存在一个拥有 20K+ 源代码模块的项目。使用 30K 的数字来证明 10 倍优势感觉像是选择性挑选。
Vercel 的澄清
在尤雨溪发布基准测试后,Vercel 发表了博文进行澄清并公开了基准测试代码。关键要点包括:
- Vite 实现仍使用默认的基于 Babel 的 React 插件,而同一基准测试中 Turbopack 和 Webpack 实现都使用 SWC——这使得比较根本不公平
- hmr_to_eval 和 hmr_to_commit 两项指标中,Turbopack 从 15ms 增加到 54ms,而 Vite 两项约 100ms 完全相同。由于 eval 到 commit 的成本是真实存在的,合理的解释是该基准测试有缺陷
- 使用 hmr_to_commit 作为测量指标更合理,这将使速度优势降至不超过 2 倍(约 100ms 与约 54ms)
尤雨溪的观点
- 30K 模块:绝大多数用户不可能遇到这样的场景,随着 Vite 采用 SWC 转换后这个阈值会更加不切实际
- 用户关心的是端到端 HMR:从保存文件到看到变化实际反映出来的时间,而非理论评测。在 Next 中,默认服务器组件(即默认设置)的端到端 HMR 速度实际上比 Vite 慢
- Vercel 利用用户心理:"10 倍更快"的表述容易让普通用户误解
- 竞争应基于公平:开源软件的竞争应该基于公开沟通、公平比较、相互尊重
总结
"比 Vite 快 10 倍"的说法只有在以下条件全部成立时才有效:Vite 没有使用相同的 SWC 转换、应用程序包含超过 30K 模块、基准测试仅测量热更新模块被评估的时间而非实际应用的时间。
Turbopack 确实很快,但"快 10 倍"的说法存在测试条件不公允的问题。Vite 在使用 SWC 后性能与 Turbopack 接近。选择工具时不应只看营销数字,而应该在实际项目中进行对比测试。Vite 已经发展到 v4 版本,性能有显著提升,这个对比数据已经不再完全适用。作为 Vite 的作者,尤雨溪表示很高兴看到像 Vercel 这样资金雄厚的公司对改进前端工具进行重大投资,甚至可能在适用时利用 Turbopack 来完善 Vite——开源软件领域健康竞争最终将使所有开发人员受益。
↑