为什么 Bun 这么快?深入解析 Zig + JavaScriptCore + Bundler 架构

系统解析 Bun 的高性能来源:Zig 实现、JSC 引擎、统一化工具链、零拷贝网络层、极简事件循环、SIMD 优化与 bundler 架构。

深入解析 Zig Runtime + JavaScriptCore + 全能 bundler 架构

Bun 的目标非常明确:做最快的 JavaScript Runtime 与“前端工具链的一体化替代品”。

Bun 之所以“快到不合理”,并不是某一个组件做得好,而是 整体架构选择 + 工程策略 + 极度工程化优化 的结果。

总结来说:

Bun 快,是因为它不是“做得比 Node 好一点”,而是整个运行时和工具链都重新设计过。

本文从架构视角解释 Bun 的核心性能来源。

1. Bun 的整体架构图(Birdor 风格)

┌──────────────────────────────────────────────┐
│                JavaScript (User Code)        │
│        CJS / ESM / Bun.imports 统一支持        │
└──────────────────────────────────────────────┘
│
▼
┌──────────────────────────────────────────────┐
│            Bun Runtime API Surface           │
│   fs / http / net / process / timers …       │
└──────────────────────────────────────────────┘
│
▼
┌──────────────────────────────┬────────────────┐
│       JavaScriptCore (JSC)   │   Zig Runtime  │
│   JIT + GC + bytecode engine │ event loop, IO│
└──────────────────────────────┴────────────────┘
│
▼
┌──────────────────────────────────────────────┐
│                    OS                        │
│          epoll / kqueue / IOCP                │
└──────────────────────────────────────────────┘

Bun 并不是一个 JS 引擎,而是:

  • Zig 写的高性能运行时
  • 使用 WebKit 的 JavaScriptCore (JSC) 作为 JS 引擎
  • 内置 超高速 bundler、transpiler、测试框架、包管理器
  • 自研事件循环和网络层

这种“从头设计一个更现代的 Node.js”的架构,是 Bun 速度的根本来源。

2. 性能来源之一:Zig 实现的 runtime(不是 C++)

Bun 的 runtime(事件循环、模块解析、文件系统调用、HTTP 层等)全部用 Zig 写。

Zig 的优势:

2.1 更可控的内存模型:无隐藏分配、无异常开销

C++ 的“隐式成本”包括:

  • 隐式拷贝
  • 隐式构造 / 析构
  • 异常机制(zero-cost exception)
  • 不可控分配行为(std::string / vector)

Zig 的设计完全相反:

  • 不允许隐藏内存分配
  • 不允许隐式错误传播
  • 所有内存都必须在代码中显式体现
  • 错误采用 error!T 形式,成本可控且无异常机制

结果:

  • 更低延迟
  • 更紧凑的机器码
  • 更符合 runtime 的需求

2.2 Zig 拥有极快的编译速度与可压缩的部署

Zig 生成的产物:

  • 无 C++ 复杂 RTTI
  • 无额外运行时依赖
  • 工程结构更清晰

相比 NodeJS 的庞大 C++ glue 层,Zig runtime 更容易做到 “持续微优化”。

2.3 工程团队可以在 runtime 层面做激进优化

因为 Zig 的可控性,Bun 选择了:

  • 更快的 UTF-8 解析器
  • 基于 SIMD 的 HTTP 解析器
  • 自研事件循环
  • 零拷贝 Buffer

这清晰解释了:
Bun 并不是“优化 Node”,而是“重写 Node 的底层”。

3. 性能来源之二:JSC(JavaScriptCore)比 V8 更适合某些场景

Node.js 和 Deno 使用 V8,而 Bun 使用 JavaScriptCore (JSC)

为什么这是优势?

3.1 JSC 的 baseline JIT 更轻量、启动更快

V8 的优化管线(Ignition → TurboFan)非常强大,但有较高的启动成本。

JSC 的 JIT 是:

  • 更小
  • 更快进入 steady-state
  • 更适合“工具链”风格的短命进程
  • 更快 eval 和 module load

这就是为什么:

  • bun runnode app.js 启动快数十毫秒
  • Bun 的 CLI 工具几乎没有“冷启动”

在 dev server 场景中是巨大的优势。

3.2 JSC 的 GC 设计对典型工具链 workload 更友好

V8 更适合大型 Web App 的对象生命周期策略;
JSC 更适合:

  • 小对象
  • 短生命周期
  • 密集解析和执行的工具链场景

Bun 恰好是“工具链一体化 Runtime”,因此这一点直接变成性能优势。

4. 性能来源之三:bundler、transpiler、resolver 全部内置(并用 Zig 写)

Bun 最大的黑科技之一,是它的 bundler:

  • 比 esbuild 还快(后者是 Go 写的,已经非常快)
  • 因为 Bun 直接基于 Zig + JSC 一体化处理整个 pipeline

Bun 的 bundling pipeline:

Parser (Zig)
↓
AST (密集优化)
↓
Transform (Zig)
↓
Codegen (Zig)
↓
Runtime Integration (JSC)

相比:

  • Webpack → JS + Node API
  • Rollup → JS 大量 AST 操作
  • esbuild → Go(仍需要和 Node 交互)

Bun 做到了:

  • 全流程一次性
  • 单进程
  • 零 context switch
  • 无需序列化/反序列化
  • 直接内存共享

这就是为什么:

bun build app.ts  # 比 esbuild 更快
bun install       # 比 npm 快十倍以上
bun test          # 比 jest 快几十倍

5. 性能来源之四:自研网络层 + 零拷贝设计

Node.js 的网络层高度依赖 libuv,而 Bun 选择了更现代、更轻量的架构。

5.1 Bun 的 HTTP 服务器比 Node 快非常多的原因:

  • SIMD 加速 HTTP 解析
  • Zero-copy buffer
  • 更轻量的事件循环
  • 没有 legacy 行为兼容的负担

例如,Bun 的 HTTP parser:

  • 用 Zig 写
  • 用大量 @Vector(SIMD)操作优化 tokenization
  • 比 Node 的 parser 快 一个数量级

6. 性能来源之五:更现代的模块解析系统

Node 的模块解析逻辑(CJS + ESM + pkg.exports + fallback)非常复杂:

  • 需要查找多层目录
  • 多种文件扩展名
  • 多种包入口策略

Bun 采用:

  • 更少的 fallback
  • 更少的猜测
  • 更标准化的 ESM 解析

模块解析越少 → 冷启动越快。

7. 性能来源之六:集成式工具链减少跨进程开销

传统工具链:

tsc → node
babel → node
jest → node
webpack → node

每一步都可能:

  • 启动 Node
  • 加载大量 JS 文件
  • 运行用户态 JS

Bun 的设计是:

Runtime, Bundler, Test Runner, Transpiler 全部在一个进程。

减少了:

  • 进程启动成本
  • 模块加载成本
  • JS AST 反复解析成本

这使得 Bun 在工具链维度的表现几乎“碾压同类”。

8. 性能来源七:更少的历史包袱

Node.js 的性能上限受历史设计限制:

  • CJS 必须支持
  • Buffer API 不能破坏
  • libuv 事件循环行为不能变
  • 大量边缘行为必须兼容 Express / React 等框架的数十亿代码

而 Bun:

  • 没有十多年前遗留的 API
  • 没有必须兼容的 C++ addon 生态
  • 没有必须保持一致的定时器行为
  • 模块解析几乎完全自由设计

越少的历史包袱 → 架构越纯粹 → 优化空间越大。

9. 为什么 Bun 快得“不合理”?(总结)

Bun 快,是因为它同时具备:

✔ Zig → 明确可控、不隐式开销的系统语言

✔ JSC → 启动快、JIT 轻量、适合工具链

✔ 自研 runtime → 网络层、事件循环高度定制化

✔ 全流程一体化 → bundler / transpiler / test / npm client 全部内置

✔ SIMD 优化 → parse JSON、解析 HTTP、基础库

✔ 零拷贝设计 → buffer 和 IO path 极短

✔ 没有历史包袱 → 不需要兼容 Node 过去 10 年的行为

一句话总结:

Bun = 现代化工程能力 + 极限优化策略 + 从底层重写 Node 的勇气。

它不是“稍微比 Node 快”,而是配置了完全不同的底层能力

10. Bun 是否会取代 Node.js?

短期:不会。
长期:Bun 会成为本地开发工具链的主流候选。

定位更像:

  • Bun → 快速构建、测试、开发(工具链革命)
  • Node → 稳定的生产 runtime
  • Deno → Web 标准化 + 更安全的 runtime

未来可能是“三分天下”,不是一方取代另一方。

结语

Bun 并不是一个“更快的 Node.js”,而是一个重新设计过的现代 JavaScript Runtime

  • 更快
  • 更轻
  • 更一致
  • 更工程化

Zig + JSC + 自研工具链,使得 Bun 在架构上具备天然的速度优势。

继续阅读

探索更多技术文章

浏览归档,发现更多关于系统设计、工具链和工程实践的内容。

全部文章 返回首页