我构建 Vercube,因为 benchmarks 不会说谎
Source: Dev.to
请提供您希望翻译的具体文本内容,我将按照要求保留源链接、格式和技术术语,仅翻译正文部分。谢谢!
Source: …
介绍
让我们从显而易见的说起:是的,这又是一个 Node.js 框架。
我知道。你也知道。某个地方,一个计数器刚刚溢出,后端开发者悄悄关闭了一个标签页。
大多数情况下,这都是正确的反应。你已经有了 NestJS、Fastify,甚至还有几个内部工具。再添加一个框架通常听起来毫无意义。
Vercube 并不是从以下想法开始的:
我们需要一个新框架。
而是从以下想法开始的:
为什么每个使用起来很舒服的框架都会变慢,而每个快速的框架又让人感觉在与它搏斗?
本文不是外部评测。我是 Vercube 的作者。这是一个关于我为何构建它的故事,哪些假设我不再接受,以及基准测试结果何时让我意识到这已经不再是一个副项目的时刻。
Source: …
问题
长期以来,后端开发感觉像是被迫在两者之间做选择。
| 方向 | 特点 |
|---|---|
| 最小化框架 | 快速、可预测、高效——但结构上很薄。你会在每个项目中重新构建模式、约定和纪律。 |
| 完整的 OOP 框架(NestJS、Ts.ED) | 装饰器、依赖注入、清晰的结构、代码在一年后仍然有意义——但你需要为此付出构建时间、启动成本和运行时开销。 |
Vercube 的出现是因为我不想在这两个世界之间不断抉择。
动机
- 长期可读性——后端代码应在第一个冲刺结束很久之后仍保持可读。
- OOP 仍然表现出色——明确的职责、显式的依赖、代码读起来像系统而不是脚本。装饰器帮助表达意图而不增加噪音。
问题不在于 OOP 本身,而在于 大多数 Node.js 框架实现它的方式。
- 大多数基于装饰器的框架严重依赖 运行时反射。
reflect-metadata成为全局依赖。- 类型在运行时被检查,容器动态推断依赖,元数据在应用已经运行时被扫描/合并。
所有这些都有代价,而代价恰恰出现在你最不想看到的地方:构建时间、冷启动、延迟和吞吐量。
Vercube 的方法
在许多方面,Vercube 就是像 routing-controllers 这类项目所追求的目标——但为现代 TypeScript、现代运行时以及将性能视为首要关注点而重新构建。
核心理念
如果把所有这些都去掉会怎样?
- 在 Vercube 中,装饰器并不是运行时技巧。它们描述结构,而不需要检查类型、扫描元数据或依赖全局反射 API。
- 它们不会在运行时做出决策,使框架保持可预测,并完全避免了通常的重反射模型。
与运行时无关的设计
- 基于 srvx 和原生
Request/Response接口构建。 - 同一套应用模型可在 Node.js、Bun 和 Deno 上直接运行,无需适配器或兼容层。
简洁的内部实现
- 如果存在某个依赖,那是因为 你自行注册了它。
- Vercube 的核心是一个 非常小的 IoC 容器——仅此而已。它负责注册和解析依赖,仅此而已。
- 没有隐藏的作用域、没有代理链、没有请求时的依赖图。容器在设置阶段完成工作;之后,请求处理尽可能直接。
这可能听起来很乏味——这正是有意为之。
在某个阶段,设计理念本身不再有趣,数字指标才会占据主导。
基准
这些基准 并不是要在每个框架之间“取胜”。它们旨在展示不同架构选择的真实成本。
所有测试使用相同的端点、相同的负载以及相同的环境。原始数据和方法论已公开——可在 GitHub 上找到:
https://github.com/vercube/benchmarks
构建时间
- 构建时间直接影响开发者体验和 CI 流水线——但很少被讨论。
- Vercube 的构建速度约比 NestJS 快 4.6 倍,在相同的设置下。
- 速度差距来源于去除了反射、元数据扫描以及复杂的引导逻辑。
- Vercube 使用 Rolldown —— 一个极快的打包工具,完美配合这种简化的架构。
冷启动
- 冷启动在无服务器环境、自动扩缩容设置以及频繁重启时尤为重要。
- Vercube 的冷启动速度比 NestJS 快约 35 %,并且 比 Ts.ED 快超过 3 倍。
吞吐量
- 吞吐量是大家普遍关注的指标。
- Vercube 提供 比 NestJS 高约 16 % 的吞吐量,同时仍然使用装饰器和依赖注入。
- 目标并非在吞吐量图表上称霸——而是保持竞争力的同时不放弃结构化。
延迟
- 平均延迟会掩盖问题。p95 能展示负载下的真实表现。
- Vercube 在负载下保持稳定,避免了在更重框架中常见的长尾延迟峰值。
全生命周期性能
- 大多数框架只谈运行时性能。
- Vercube 同样关注 首次请求之前发生的所有事情:构建时间、冷启动、启动内存。
- 在现代系统——CI 密集的工作流、无服务器部署、短生命周期实例——这些成本会迅速累积。基准显示 Vercube 在整个生命周期中表现良好,而不仅仅是在请求处理阶段。
为什么它有效
结果背后没有单一的技巧。性能来源于消除整类开销:
- 没有运行时反射
- 没有元数据扫描
- 没有请求时的依赖解析
- 没有抽象层在每次调用上
所有昂贵的操作只会一次发生。每次请求运行的只是普通的 JavaScript。
这也意味着更少的意外。当某件事表现出特定方式时,通常很容易看出原因。
许多开发者把装饰器与缓慢、过度设计的系统联系在一起。这是一个工具问题——而不是范式问题。
Vercube 表明,你可以保留面向对象、保留装饰器、保持清晰的结构——仍然能够达到通常只属于更简约框架的性能指标。
Conclusion
我并不是仅仅为了证明性能而构建 Vercube;我构建它是为了 重新夺回在框架堆砌隐藏成本时丢失的开发者体验。通过剥离反射、元数据扫描以及运行时沉重的抽象,Vercube 提供了一种熟悉、结构化的面向对象编程体验 而不牺牲速度。
如果你厌倦了在 “fast but bare‑bones”(快速但功能简陋) 和 “feature‑rich but sluggish”(功能丰富但迟缓) 之间做选择,试试 Vercube 吧——数字、代码和理念全部公开,供你检视。
关于框架的观点
我之所以构建它,是因为我想再次享受编写后端代码的乐趣——而不必为构建时间、启动时间或运行时性能的舒适性付出代价。
基准测试之所以重要,是因为它们在讨论中剔除了主观意见。你不必喜欢其设计或认同其哲学,只需看数字即可。
而这些数字表明,OOP——只要谨慎使用——仍然在现代后端开发中占有一席之地。