基准测试
编译与打包
衡量什么
这些基准测试衡量的是编译与打包速度,而非生产环境服务性能。
Next.js 与 vinext 的默认做法有本质不同:Next.js 在构建时静态预渲染页面 (构建更慢,但静态内容的生成服务更快),而 vinext 在每次请求时对所有页面做服务端渲染。 为了让比较旗鼓相当,基准应用使用export const dynamic = "force-dynamic"关掉 Next.js 的静态预渲染——两个框架做着相同的工作:编译、打包,以及准备服务端渲染的路由。
基准应用是一个共享的、33 条路由的 App Router 应用(服务端组件、客户端组件、动态路由、嵌套布局、API 路由), 由两种工具以相同方式构建。我们比较 Next.js(Turbopack)与 vinext(Vite 8)。 Turbopack 与 Rolldown 都会跨核并行,因此在核数更多的机器上结果可能有显著差异。
生产构建时间
运行 5 次,用 hyperfine 计时。
客户端包体大小
每次构建的 gzip 输出。
开发服务器冷启动
运行 10 次,随机化执行顺序。每次运行前都会清空 Vite 的依赖优化缓存。
包体大小差异的来源
对构建输出的分析显示了两个主要因素:
1 · Tree-shaking
Vite/Rolldown 产出的 React+ReactDOM 包比 Next.js/Turbopack 更小。 Rolldown 更激进的死代码消除贡献了整体差异的大约一半。
2 · 框架开销
Next.js 比 vinext 更轻量的客户端运行时携带了更多的客户端基础设施 (路由器、Turbopack 运行时加载器、预取、错误处理)。
两个框架都交付相同的应用代码,以及相同的 RSC 客户端运行时(react-server-dom-webpack)。 差异在于有多少 React 实现在 tree-shaking 后存活下来,以及每个工具额外加入了多少框架管线。
复现
基准测试在 GitHub CI runner(2 核 Ubuntu)上、每次合并到 main 时运行。 每个结果中都记录了确切的框架版本。
node benchmarks/run.mjs --runs=5 --dev-runs=10