Node 生态孵化了许多 Web 框架,但究竟谁能脱颖而出、荣膺“性能之王”呢?
在本文中,我们会针对一个简单的 hello world 案例,测评 Node 的原生服务器、Express、Fastify、Hapi、Koa、Restify、NestJS、NestJS、Hyper Express 和 AdonisJS 的性能。当然啦,hello world 案例和现实世界的开发情况可能有所出入。但是,hello world 始终是测试的起点。以后我们可能测评更复杂的案例,包括静态文件服务器、JSON 处理等。
免责声明
本文属于是语冰的直男翻译了属于是,略有删改,仅供粉丝参考。英文原味版请传送 Node.js: The fastest web framework in 2024。
测试设置Node 版本是 v21.5.0。负载测试器是用 Go 语言编写的 Bombardier。
我们也涵盖了 Node 的原生服务器。这为所有其他框架提供了良好的测评基准。地球人都知道,Node 的原生服务器几乎也是一个简单的服务器。
每个框架的 App 代码如下所示:
原生服务器import http from 'node:http'const reqHandler = (req, resp) => { try { if (req.method !== 'GET') { return resp.writeHead(405).end() } if (req.url !== '/') { return resp.writeHead(404).end() } resp.writeHead(200, { 'content-type': 'text/plain' }) resp.end('Hello world') } catch (e) { resp.writeHead(500).end() }}http.createServer(reqHandler).listen(3000)Express这里 Etag 被禁用,因为其他框架默认不发送。
import express from 'express'const app = express()const reqHandler = (req, res) => { res.send('Hello World!')}app.disable('etag')app.get('/', reqHandler)app.listen(3000, () => console.log('Listening on 3000'))Fastifyimport Fastify from 'fastify'const fastify = Fastify({ logger: false})const reqHandler = (request, reply) => { reply.send('Hello World!')}fastify.get('/', reqHandler)fastify.listen({ port: 3000 })Koaimport Koa from 'koa'import Router from '@koa/router'const app = new Koa()const router = new Router()const reqHandler = (ctx, next) => { ctx.body = 'Hello World!'}router.get('/', reqHandler)app.use(router.routes()).use(router.allowedMethods())app.listen(3000)Hapiimport Hapi from '@hapi/hapi'const server = Hapi.server({ port: 3000, host: '127.0.0.1'})const reqHandler = (request, h) => { return 'Hello World!'}server.route({ method: 'GET', path: '/', handler: reqHandler})server.start()Restifyimport restify from 'restify'const reqHandler = (req, res, next) => { res.contentType = 'text/plain' res.send('Hello World!') next()}const server = restify.createServer()server.get('/', reqHandler)server.listen(3000)Hyper Expressimport HyperExpress from 'hyper-express'const webserver = new HyperExpress.Server()const reqHandler = (request, response) => { response.send('Hello World!')}webserver.get('/', reqHandler)webserver.listen(3000)NestJSNestJS App 的代码是通过其 CLI 生成的。这里只展示若干相关文件。
// main.tsimport { NestFactory } from '@nestjs/core'import { AppModule } from './app.module'async function bootstrap() { const app = await NestFactory.create(AppModule) app.getHttpAdapter().getInstance().set('etag', false) await app.listen(3000)}bootstrap()// app.module.tsimport { Module } from '@nestjs/common'import { AppController } from './app.controller'import { AppService } from './app.service'@Module({ imports: [], controllers: [AppController], providers: [AppService]})export AppModule {}import { Controller, Get } from '@nestjs/common'import { AppService } from './app.service'// app.controller.ts@Controller()export AppController { constructor(private readonly appService: AppService) {} @Get() getHello(): string { return this.appService.getHello() }}// app.service.tsimport { Injectable } from '@nestjs/common'@Injectable()export AppService { getHello(): string { return 'Hello World!' }}NestJS + Fastify默认情况下,NestJS 使用 Express 适配器。因此,性能比 Express 稍差,它本身是本次测评中最慢的。幸运的是,NestJS 允许配置 Fastify 适配器而不是 Express。
// main.tsimport { NestFactory } from '@nestjs/core'import { FastifyAdapter, NestFastifyApplication} from '@nestjs/platform-fastify'import { AppModule } from './app.module'async function bootstrap() { const app = await NestFactory.create<NestFastifyApplication>( AppModule, new FastifyAdapter() ) await app.listen(3000)}bootstrap()所有其他文件与 NestJS + Express 适配器相同。
AdonisJSAdonisJS 的 App 代码是通过其 CLI 生成的。这里只展示若干相关文件。
// server.tsimport 'reflect-metadata'import sourceMapSupport from 'source-map-support'import { Ignitor } from '@adonisjs/core/build/standalone'sourceMapSupport.install({ handleUncaughtExceptions: false })new Ignitor(__dirname).httpServer().start()// routes.tsimport Route from '@ioc:Adonis/Core/Route'Route.get('/', async () => { return 'Hello World!'})跑分结果100 个并发连接总共执行 5M 个请求。除了延迟之外,我还收集了 CPU 和内存占用情况。仅仅拥有高 RPS(每秒请求数)是不够的。我们还需要了解 RPS 的成本。
测评结果如图表所示:
执行时间成本:
RPS(每秒请求数):
延迟:
资源使用情况:
最终判决在开始科学分析之前,我们应该注意到,这是功能丰富和常规框架的混合体。其中,NestJS 和 AdonisJS 是我行我素的框架,与所有其他框架相比,其功能明显更多。将 NestJS 与 Koa 进行比较可能并不公平。
出乎意料的是,HyperExpress 成为了本次跑分的黑马。HyperExpress 比 Fastify 快约 2 倍,比 Express 快 9 倍,比其他降价快约 3~4 倍。HyperExpress 以更低的资源成本提供卓越的性能。
在别人给我推荐 HyperExpress 之前,我还从未听说过它。当我追求接近 Node 原生服务器的性能时,我总是会优先考虑 Fastify。
所以,本期测评跑分的“性能之王”是 HyperExpress。
但这只是关于什么都不做的简单“hello world”服务器。对于更复杂的测评,冠军的胜算可能不会那么大。
本期话题是 —— 你最喜爱或常用的 Node 框架是哪一个?
作者:前端暴走团链接:https://juejin.cn/post/7348726802448252965