Next.js Turbopack 性能追踪实战:用 NEXT_TURBOPACK_TRACING 生成并分析 trace-turbopack.bin
Turbopack 底层的 turbo-tasks 引擎自带一套 tracing 机制,可以记录每个函数执行的耗时与内存消耗,是调试和优化 Next.js 构建/开发服务器性能的核心工具。本文基于当前仓库的贡献文档与 CLI 源码,完整讲解如何通过环境变量 NEXT_TURBOPACK_TRACING(或 --internal-trace 参数)打开追踪、产出二进制 trace 文件,再用 trace-server 与可视化 Viewer 进行多维度分析。读完本文,你可以独立复现"采集 trace → 本地起服务 → 浏览器看火焰/聚合视图"的完整性能分析流程。
一、为什么需要 Tracing:turbo-tasks 的执行与资源追踪
turbo-tasks 是 Turbopack 的编译执行引擎,其自带的 tracing 功能可以记录每一次执行的运行时间(runtime)和内存消耗(memory consumption)。这对两类场景尤其有用:
- 调试性能问题:某次
next dev冷启动或next build明显变慢,需要定位是哪个环节(文件读取、模块解析、转译、CSS 处理……)占用了时间; - 优化 Turbopack 本身:开发者在修改 Rust 侧代码前后,对比 trace 数据确认改动是否生效。
在 Next.js 中,这套能力通过环境变量 NEXT_TURBOPACK_TRACING 对外暴露。
二、开启追踪:NEXT_TURBOPACK_TRACING 的四个预设档位
在 Next.js 中,只需设置 NEXT_TURBOPACK_TRACING 即可启用追踪。该变量支持以下几个特殊预设值(档位逐级包含更底层的日志):
| 预设值 | 说明 |
|---|---|
1 或 overview |
基础的用户级(user level)追踪。这是已发布 Next.js 版本中唯一可用的档位 |
next |
与 overview 相同,但额外包含 Next.js 自有 crate 的 debug 和 trace 级别日志 |
turbopack |
与 next 相同,但再包含 Turbopack 自有 crate 的 debug 和 trace 级别日志 |
turbo-tasks |
与 turbopack 相同,并对每个 Turbo-Engine 函数执行做逐条的详细追踪(verbose tracing) |
例如在开发服务器上开启:
NEXT_TURBOPACK_TRACING=overview pnpm next dev
除了预设值之外,该变量还支持 tracing_subscriber::filter::EnvFilter 的任意 directives 语法,因此可以用 Rust tracing 生态的标准过滤器来按 crate、按级别精细控制输出,例如组合多个过滤规则分别指定不同模块的日志级别。
发布版本 vs 自定义构建的重要限制
注意:普通的 canary / stable 发布版本只包含 info 级别的追踪(即预设表中
overview所对应的用户级追踪),这是面向最终用户的设计。若要获得
next、turbopack、turbo-tasks等更详细的日志,必须自己编译一份 Next.js(自定义构建)。构建方式参见仓库中的 开发指南。
这条限制解释了为什么预设要分层:发布包中裁剪掉 debug/trace 日志,避免在普通用户场景下产生过大的 trace 文件与性能开销;而贡献者从源码构建时则能拿到全量数据。
三、CLI 侧的落地:--internal-trace 与 .next-profiles 目录
从当前仓库的 CLI 源码可以看到,--internal-trace 参数就是 NEXT_TURBOPACK_TRACING 的命令行封装,next build 与 next dev 两条命令均支持(见 CLI 入口 与 dev 命令):
# next build / next dev 均支持
next build --internal-trace # 默认档位 all → 映射为 turbo-tasks
next build --internal-trace overview # 仅用户级追踪
next dev --internal-trace overview
源码中的映射逻辑很直接(next.ts):
if (options.internalTrace) {
process.env.NEXT_TURBOPACK_TRACING =
options.internalTrace === 'all'
? 'turbo-tasks'
: String(options.internalTrace)
}
即 --internal-trace all(默认)等价于 NEXT_TURBOPACK_TRACING=turbo-tasks,--internal-trace overview 等价于 overview。
当检测到追踪开启时,CLI 入口还会调用 setupProfilesDir(next.ts)自动创建 .next-profiles 目录(并写入 .gitignore 防止误提交)。注意源码中的判断:只要设置了 NEXT_TURBOPACK_TRACING 且未设置 NEXT_TURBOPACK_TRACING_PATH(后者用于重定向输出位置),就会创建该目录。
追踪过程中,Next.js 最终会把 tracing 信息以二进制格式写入:
.next-profiles/trace-turbopack.bin
从 upload-trace.ts 可以看到该二进制文件的魔数头部是 TRACEv0:
// Turbopack trace files start with this magic header (written by trace_writer.rs)
const TURBOPACK_TRACE_HEADER = Buffer.from('TRACEv0')
仓库中配套的上传工具(packages/next/src/cli/internal/upload-trace.ts)会扫描 .next-profiles 目录下 *.cpuprofile 与 trace-turbopack.bin 文件,校验头部后上传,可供参考其文件校验逻辑(空文件跳过、TRACEv0 头部校验、64KB 分块进度流)。
四、可视化:turbo-trace-viewer 与 trace-server
拿到 .next-profiles/trace-turbopack.bin 后,用官方的 turbo-trace-viewer 工具进行可视化。该工具通过 localhost 的 57475 端口 WebSocket 连接到一个 trace-server 来读取二进制 trace。启动方式有两种:
# 方式一:直接跑 Rust 二进制
cargo run --bin turbo-trace-server --release -- /path/to/your/trace-turbopack.bin
# 方式二:Next.js 仓库内部命令(源码构建环境)
pnpm next internal trace .next-profiles/trace-turbopack.bin
服务启动后,在浏览器中打开官方 trace viewer 页面(https://trace.nextjs.org/)即可连接并查看。
性能提示:运行 trace server 务必使用
--release构建。trace server 在 debug 模式下非常慢,release 构建能带来约 10 倍的性能差距,这在处理大体积 trace 文件时体感非常明显。
五、读懂 Viewer:五种可视化模式与五种数值维度
trace viewer 的核心价值在于"多个视角 × 多个指标"的自由组合。
5.1 可视化模式(如何组织 Span 的树结构)
- Aggregated spans:同一父节点下同名 span 聚合为一组,适合快速找到"哪类操作总耗时高";
- Individual spans:每个 span 单独展示,适合逐条审查;
- ... in order:span 按发生顺序排列,适合还原执行时间线;
- ... by value:按数值大小排序,数值最大的 span 排在最前,适合快速定位热点;
- Bottom-up view:不显示 span 的总耗时,而显示其 self value(自身耗时,不含子 span),适合区分"自身慢"和"子任务慢"。
5.2 数值模式(每个 span 用什么指标衡量)
- Duration:span 的 CPU 时间;
- Allocated Memory:span 执行期间分配的内存量;
- Allocations:span 执行期间的分配次数;
- Deallocated Memory:span 执行期间释放的内存量;
- Persistently Allocated Memory:span 期间分配但未被释放、"存活"过该 span 的内存量——这是排查构建/编译过程中内存持续增长的关键指标。
实际排查经验路径通常是:先用 Duration + by value 找到总耗时热点,再切到 Bottom-up view 判断是自身开销还是子 span 开销,最后切到内存类指标确认是否存在随编译进程累积的内存增长。
六、典型工作流小结
- 选择档位:已发布版本用
NEXT_TURBOPACK_TRACING=overview(或next build --internal-trace overview);贡献者从源码构建后可用next/turbopack/turbo-tasks逐级加细节; - 运行:执行
next dev/next build,触发需要分析的构建或请求; - 采集:进程退出后得到
.next-profiles/trace-turbopack.bin(文件以TRACEv0头部标识); - 服务:
cargo run --bin turbo-trace-server --release -- .next-profiles/trace-turbopack.bin(务必--release); - 分析:打开 trace viewer,按 5.1 / 5.2 的模式组合定位热点 span 与内存增长。
七、相关入口速查
- 本文对应文档:contributing/turbopack/tracing.md
- 源码构建 Next.js(解锁更详细追踪档位):contributing/core/developing.md
- CLI 追踪参数与 profiles 目录逻辑:packages/next/src/bin/next.ts
- trace 文件校验与上传逻辑(
TRACEv0头部):packages/next/src/cli/internal/upload-trace.ts - dev 进程中环境变量透传:packages/next/src/cli/next-dev.ts
适用前提提示:next/turbopack/turbo-tasks 档位仅在自行编译的 Next.js 构建中生效;--internal-trace 属于内部(internal)调试参数,面向贡献者与深度排障场景,普通项目日常使用 overview 档位即可。
atomcodeClaude Code 的开源替代方案。连接任意大模型,编辑代码,运行命令,自动验证 — 全自动执行。用 Rust 构建,极致性能。 | An open-source alternative to Claude Code. Connect any LLM, edit code, run commands, and verify changes — autonomously. Built in Rust for speed. Get StartedRust0622
Hy4-previewHy4 preview 是由腾讯混元团队研发的新一代混合专家(MoE)旗舰模型。模型总参数量 770B,每个 token 激活 49B,主干共包含78层,第一层采用标准 FFN,其余 77 层均为 MoE 结构,每层包含 256 个路由专家与 1 个共享专家,每个 token 激活 top-8 路由专家及共享专家。主干之外原生内置 1 层 MTP(总参数量 10B,激活 0.7B)以支持投机解码。Python00
GLM-5.3GLM-5.3 与 GLM-5.2 使用相同的基座模型——所有提升均来自后训练。与 GLM-5.2 相比,它在复杂编程和长程任务上的表现显著提升。Jinja00
GLM-5.3-FlashGLM-5.3-Flash (320B-A18B),是GLM-5系列的首个原生多模态模型。320B总参数,能力超过GLM-5.2Jinja00
Spark-X2.5-4BSpark-X2.5-4B 旨在让强大的 AI 更实用、更高效、更易获得。在广泛日常任务中表现强劲,涵盖对话、写作、翻译、推理、编码、工具调用以及智能体工作流,并在同等规模的开源模型中取得领先成绩。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00
Spark-X2.5-1.7BSpark-X2.5-1.7B 旨在让强大的 AI 更加实用、高效且易于获取。这些模型在广泛的日常任务中表现出色,涵盖对话、写作、翻译、推理、编程、工具调用和智能体工作流,并在同等规模的开源模型中取得领先结果。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00