最近前端领域又火了一个东西,名字是bun
(官网:bun.sh),这个玩意野心很大,对标 NodeJS,以前类似的东西只有 Rust 写的 Deno。
Incredibly fast JavaScript runtime, bundler, test runner, and package manager -- all in one - bun - Github
Bun 是一个 无比快的 JS 运行时,打包工具,测试工具,以及包管理工具。
Bun 的最大卖点就是 "快!",这和当初 Vite 出来时的宣传标语有点类似,不过 Vite 是对标 Webpack,两者在不同领域,这里就不展开了。
这篇文章的目的是尽可能探索 bun 为什么这么快。为了节省时间和快速写完,本文仅从理论和感官上论述,没有任何性能上的实验,感兴趣的朋友可以自行使用 benchmark 工具来测试。
一、语言
NodeJS 是基于 C/C++ 的,这也让很多人认为 Bun 比它快根本没有道理,毕竟通常大家印象里 C/C++ 就是世界上最快的语言。
1.1 Zig
地址:ziglang.org
Bun 是基于 zig 语言的,有意思的是,这门语言是自称比 C 要快的
Speaking of performance, Zig is faster than C. ------ Zig 官方文档
我大概看了一下,这门语言创立之初的目的之一很大可能就是为了在"开箱即用"的状态下,大部分时候会比 C/C++ 快,毕竟 C/C++ 在性能上有很多奇技淫巧,非专家不可优化,而 Zig 的默认编译工具就是 LLVM,这玩意以前就是给 C/C++ 用的。
所以,从出发点来说,基于 Zig 的 bun 在语言性能上可能是不输基于 C/C++ 的 NodeJS 的。
在 Reddit 上有一个讨论,普遍的答案是纯语言性能来说,C/C++/Rust/Zig 很难有明确的差异。
1.2 语言构成占比
这两个语言在 Github 上都是开源的,我们可以很容易看到现在 Node 和 Bun 各自使用语言的占比,
不难看出,Node 实际上由 C/C++ 写的部分占比只有 20%+,现在很多标准库大部分都是纯 JS 了。换句话说,在用 NodeJS 作为运行时的时候,大部分时候跑的还是 JS 代码。
再看 Bun,40%+的 Zig,30%+ 的 C++,这里结论是 Bun 用 C++ 的占比都比 Node 大,更别提极为少量的 JS/TS 了。
当然,从语言构成占比来分析性能可能不是太科学,正如文章一开始说的那样,本文仅从粗略的分析解释为什么 bun 会很快,更多实测结果还需要后续的分析。
二、TypeScript 运行时
按照 Bun 官网所说,
Bun can directly execute
.ts
and.tsx
files just like vanilla JavaScriptBun 可以执行 ts 和 tsx 文件。
Because Bun can directly execute TypeScript, you may not need to transpile your TypeScript to run in production.
因为 Bun 可以直接执行 TypeScript,你在生产环境下可能不需要作一次转译。
当然,Bun 也内置了类似 Babel 和 tsc 的能力,即提供 TS to JS 的功能,不过这是为了在开发时或者浏览器里运行的时候方便开发者调试。
说到这里,可能有人不太理解,怎么可能可以直接执行ts呢?(你在搞笑吧?),其实通过抽象语法树(AST)工具,比如 tree-sitter 是很容易自行去编译一门语言的,甚至是自创的语言。具体 bun 是怎么做的我不太清楚,需要细看代码,应该也是借助了 Zig 生态圈里的某些工具吧。
三、自己就是 bundler + package mangaer
3.1 打包器
Bundle 的作用是把模块化的各个 JS 文件(甚至其它文件)打包到统一的出口,在 NodeJS 的生态下,我们常见的 bunder 有:webpack, rollup, tsup, vite, esbuild(基于Go), swc(基于Rust) ... 后两者也是以快著称,而 bun 是自带基于 Zig 的 bundler 的,所以它很快这件事情也是可以理解的。另外,它也不需要做 JS 到其它语言的这一层调用转换(势必会消耗时间),它是 all-in-one 的。
3.2 包管理器
在 Node 的生态圈下,包管理器的发展是 npm -> yarn -> pnpm,这个趋势也是越来越快的。pnpm 是通过某些技巧来避免重复下载和包的复用。没有例外的是,现代 Node 的包管理器都是基于纯 JS 写的,所以它比较慢也是正常的。(只有技巧,没有质变)
Bun 自带基于 Zig 的包管理器,这里又赢了一次,另外,
Bun uses the fastest system calls available on each operating system to make installs faster than you'd think possible
Bun 在每一个操作系统上都适配了最快的(fastest)系统调用来让 install 的过程更快。 -- Bun 官方文档
到这里也能看出来,bun 的作者确实是非常用心的,也是很懂现代前端的各种特点的,直接从最基础的地方重写一套,可以说是非常卷了。
结尾
OK,写到这里基本上总结完了 "bun 为什么这么快"这个问题,当然它还有其它特性,需要用户慢慢探索。
2023年9月8号,bun 正式发布 1.0 版本:bun.sh/blog/bun-v1...
这意味着,站在作者的层面,认为第一阶段开发工作基本告一段落,或许可以在生产环境中尝试了。当然,更多的问题,bug,以及性能上的优劣,可能还需要广大开发者用户们慢慢探索了!