如果你深耕 JavaScript 技术生态,一定看过那些令人惊叹的性能基准测试。你大概率也见过这样的场景:bun install 执行完毕的瞬间,npm install 的进度条甚至还没加载出雏形。
自然而然,社区里所有人都在问同一个问题:为什么 Bun 能这么快?
大家最先得出的结论简单直白:Bun 是用 Zig 写的,Deno 基于 Rust 开发,所以 Zig 肯定比 Rust 更快。
但这个答案,只说对了冰山一角(10%) 。哪怕把 Deno 的架构原封不动移植到 Zig 上,它也达不到 Bun 的跑分水准;反过来,就算用 Rust 重写一遍 Bun,它的速度依然能轻松碾压 Deno。
二者的性能差距,根源不在于单一因素,而是由三大核心维度共同决定的:JavaScript 引擎选型、底层架构设计,以及编程语言特性。
接下来,我们就拆解清楚,为什么 Bun 能把 Deno 远远甩在身后。
一、核心决胜点:JavaScriptCore 与 V8 的引擎对决
决定 Bun 极致速度的头号关键,根本不是它的开发语言,而是执行 JavaScript 代码的「内核」——JavaScript 引擎。
Deno(还有 Node.js)都基于 V8 引擎 开发,这款由谷歌为 Chrome 打造的引擎,堪称软件工程的杰作。V8 的设计初衷,是应对浏览器中长期、高负载的计算场景,它会在代码运行过程中做极致的即时编译(JIT)优化。但这份强大的背后,是极高的复杂性:V8 存在显著的启动成本—— 在执行哪怕一行代码之前,它都需要消耗不少时间和内存完成初始化。
而 Bun 选择的是 JavaScriptCore(简称 JSC) ,这款由苹果为 Safari(WebKit 内核)打造的引擎,诞生之初就带着截然不同的设计优先级:适配移动设备。手机的内存和电量都极其有限,因此 JSC 从底层就被设计为瞬时启动、极致低内存占用的形态。
最终的性能差距体现在这里:当你运行一段脚本时,往往 Bun 已经完成引擎初始化、跑完所有代码,Deno 这边的 V8 引擎还没完成启动流程。对于日常高频使用的 CLI 工具(比如单元测试、项目打包)来说,「启动耗时」就是决定体验的核心指标。
二、Tokio 抽象开销 vs 从零造轮子的极致精简
这一部分,终于轮到 Zig vs Rust 的话题,但关键从来都不是「哪种语言的编译器更快」。
首先要明确:Rust 本身是一门极致高效的编程语言。但 Deno 的开发,重度依赖 Tokio—— 这款 Rust 生态的标杆式异步运行时。Tokio 本身无可挑剔:内存安全、稳定可靠,能完美处理异步 IO 的各类复杂场景。可它的定位是通用型异步运行时,为了兼顾通用性和安全性,Tokio 封装了多层抽象,也做了大量的边界场景兼容,这些设计都会产生不可避免的抽象开销。
而 Bun 走了一条完全相反的路。
Bun 没有复用任何通用的第三方库,其核心逻辑都由作者 Jarred Sumner 基于 Zig 从零手写。Zig 常被称作「现代化的 C 语言」:它支持开发者手动管理内存,没有垃圾回收的负担,同时又摆脱了 Rust 中严苛的所有权模型带来的额外开销,能让开发者拿到最纯粹的底层控制权。
Bun 不用 Tokio,也不用 Node.js 标配的 libuv;它的 HTTP 服务、文件系统的事件循环、代码转译器,全都是自研实现。
为 Bun 量身定制的这些核心组件,彻底砍掉了不必要的「抽象税」:剔除了用不上的功能,只对高频调用的执行链路做极致优化。
可以用两张极简的调用链路,看清二者的差异:
- Deno 的执行链路:Rust 业务代码 → Tokio 抽象层 → 操作系统内核
- Bun 的执行链路:Zig 业务代码 → 操作系统内核
更少的调用层级,就意味着更低的延迟、更少的性能损耗。
三、「全能瑞士军刀」vs「专精手术刀」的设计取舍
Deno 在 Rust 生态里,算得上是「循规蹈矩的优等生」。它大量复用生态中久经考验的成熟库,用模块化的方式搭建整个项目:
- 用 swc 做 TypeScript/JSX 的代码转译
- 用 serde 处理 JSON 解析
- 用 hyper/deno_http 实现网络请求能力
这种设计让 Deno 具备优秀的模块化和安全性,但不同的第三方库之间需要「胶水代码」做衔接,这又会产生额外的性能损耗。
反观 Bun,它是一个不折不扣的单体架构(Monolith) :
- 自研基于 Zig 的代码转译器,速度比 swc 更快
- 自研专属的 JSON 解析器
- 自研 WebSocket 实现
当你能掌控整条技术栈的每一个环节,就能做很多「剑走偏锋」的极致优化。比如 Bun 会大胆使用内存映射(mmap)加载文件,也会在底层代码中实现激进的缓存策略 —— 这些深度定制的优化,根本没法无缝适配通用的第三方库,强行接入只会破坏库的模块化设计。
结语:Zig 真的比 Rust 更好吗?
答案是:不是。Rust 和 Zig,只是为不同需求而生的工具。
Rust 把内存安全和杜绝数据竞争放在了所有设计的首位。这种特性,让它成为大型协作项目的最优解 —— 毕竟在多人维护的复杂工程里,安全性是底线,容不得半点妥协。
而 Zig 的核心优势是极致控制权与性能榨取。它能让开发者写出看似高级的代码,最终编译出的机器码,却能媲美手工调优的 C 语言汇编,几乎没有多余开销。
总结来说,Bun 比 Deno 更快,从来都不是因为 Rust 本身「慢」,真正的原因有三点:
- Bun 选用的 JavaScriptCore 引擎,启动速度远胜 Deno 的 V8 引擎;
- Bun 自研的定制化底层架构,砍掉了 Tokio 这类通用库带来的抽象开销;
- Zig 语言赋予开发者的底层操控能力,让很多极致的系统级优化得以落地 —— 这些优化,在 Rust 中要么难以实现,要么会牺牲掉语言的安全特性。
「Zig 对决 Rust」的论调,确实是吸睛的标题党,但这场性能之争的真相,本质是工具的取舍:Bun 选择做一把专攻极致性能的「手术刀」,而 Deno 选择做一把兼顾安全、兼容、易用的「瑞士军刀」。