首页
/ Next.js Turbopack 性能追踪实战:用 NEXT_TURBOPACK_TRACING 生成并分析 trace-turbopack.bin

Next.js Turbopack 性能追踪实战:用 NEXT_TURBOPACK_TRACING 生成并分析 trace-turbopack.bin

2026-09-04 21:40:49作者:曹令琨Iris

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 即可启用追踪。该变量支持以下几个特殊预设值(档位逐级包含更底层的日志):

预设值 说明
1overview 基础的用户级(user level)追踪。这是已发布 Next.js 版本中唯一可用的档位
next overview 相同,但额外包含 Next.js 自有 crate 的 debugtrace 级别日志
turbopack next 相同,但再包含 Turbopack 自有 crate 的 debugtrace 级别日志
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 所对应的用户级追踪),这是面向最终用户的设计。

若要获得 nextturbopackturbo-tasks 等更详细的日志,必须自己编译一份 Next.js(自定义构建)。构建方式参见仓库中的 开发指南

这条限制解释了为什么预设要分层:发布包中裁剪掉 debug/trace 日志,避免在普通用户场景下产生过大的 trace 文件与性能开销;而贡献者从源码构建时则能拿到全量数据。

三、CLI 侧的落地:--internal-trace 与 .next-profiles 目录

从当前仓库的 CLI 源码可以看到,--internal-trace 参数就是 NEXT_TURBOPACK_TRACING 的命令行封装,next buildnext 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 入口还会调用 setupProfilesDirnext.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 目录下 *.cpuprofiletrace-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 开销,最后切到内存类指标确认是否存在随编译进程累积的内存增长。

六、典型工作流小结

  1. 选择档位:已发布版本用 NEXT_TURBOPACK_TRACING=overview(或 next build --internal-trace overview);贡献者从源码构建后可用 next / turbopack / turbo-tasks 逐级加细节;
  2. 运行:执行 next dev / next build,触发需要分析的构建或请求;
  3. 采集:进程退出后得到 .next-profiles/trace-turbopack.bin(文件以 TRACEv0 头部标识);
  4. 服务cargo run --bin turbo-trace-server --release -- .next-profiles/trace-turbopack.bin(务必 --release);
  5. 分析:打开 trace viewer,按 5.1 / 5.2 的模式组合定位热点 span 与内存增长。

七、相关入口速查

适用前提提示:next/turbopack/turbo-tasks 档位仅在自行编译的 Next.js 构建中生效;--internal-trace 属于内部(internal)调试参数,面向贡献者与深度排障场景,普通项目日常使用 overview 档位即可。

登录后查看全文
热门项目推荐
相关项目推荐

项目优选

收起
kernelkernel
deepin linux kernel
C
33
18
ops-transformerops-transformer
本项目是CANN提供的transformer类大模型算子库,实现网络在NPU上加速计算。
C++
1.12 K
2.72 K
kernelkernel
openEuler内核是openEuler操作系统的核心,既是系统性能与稳定性的基石,也是连接处理器、设备与服务的桥梁。
C
527
590
ops-nnops-nn
本项目是CANN提供的神经网络类计算算子库,实现网络在NPU上加速计算。
C++
904
1.82 K
pytorchpytorch
作为 Ascend for PyTorch 社区的核心组件,TorchNPU 是昇腾专为 PyTorch 打造的深度学习适配插件,使 PyTorch 框架能够直接调用昇腾 NPU,为开发者提供昇腾 AI 处理器的超强算力。
Python
854
1.34 K
docsdocs
暂无描述
Markdown
889
5.78 K
jiuwenswarmjiuwenswarm
JiuwenSwarm 是一款基于openJiuwen开发的智能AI Agent,它能够将大语言模型的强大能力,通过你日常使用的各类通讯应用,直接延伸至你的指尖。
Python
3.52 K
1.01 K
ops-mathops-math
本项目是CANN提供的数学类基础计算算子库,实现网络在NPU上加速计算。
C++
1.33 K
1.45 K
cann-learning-hubcann-learning-hub
CANN 学习中心仓,支持在线互动运行、边学边练,提供教程、示例与优化方案,一站式助力昇腾开发者快速上手。
Jupyter Notebook
981
502
AscendNPU-IRAscendNPU-IR
AscendNPU-IR是基于MLIR(Multi-Level Intermediate Representation)构建的,面向昇腾亲和算子编译时使用的中间表示,提供昇腾完备表达能力,通过编译优化提升昇腾AI处理器计算效率,支持通过生态框架使能昇腾AI处理器与深度调优
C++
540
384