Node 框架性能之王,2024 最快 Web 框架硬核测评

大家好,这里是大家的林语冰。

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 代码如下所示:

原生服务器

js 复制代码
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 被禁用,因为其他框架默认不发送。

js 复制代码
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'))

Fastify

js 复制代码
import Fastify from 'fastify'

const fastify = Fastify({
  logger: false
})
const reqHandler = (request, reply) => {
  reply.send('Hello World!')
}

fastify.get('/', reqHandler)
fastify.listen({ port: 3000 })

Koa

js 复制代码
import 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)

Hapi

js 复制代码
import 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()

Restify

js 复制代码
import 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 Express

js 复制代码
import HyperExpress from 'hyper-express'

const webserver = new HyperExpress.Server()
const reqHandler = (request, response) => {
  response.send('Hello World!')
}

webserver.get('/', reqHandler)
webserver.listen(3000)

NestJS

NestJS App 的代码是通过其 CLI 生成的。这里只展示若干相关文件。

ts 复制代码
// main.ts
import { 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.ts
import { Module } from '@nestjs/common'
import { AppController } from './app.controller'
import { AppService } from './app.service'

@Module({
  imports: [],
  controllers: [AppController],
  providers: [AppService]
})
export class AppModule {}

import { Controller, Get } from '@nestjs/common'
import { AppService } from './app.service'

// app.controller.ts
@Controller()
export class AppController {
  constructor(private readonly appService: AppService) {}

  @Get()
  getHello(): string {
    return this.appService.getHello()
  }
}

// app.service.ts
import { Injectable } from '@nestjs/common'

@Injectable()
export class AppService {
  getHello(): string {
    return 'Hello World!'
  }
}

NestJS + Fastify

默认情况下,NestJS 使用 Express 适配器。因此,性能比 Express 稍差,它本身是本次测评中最慢的。幸运的是,NestJS 允许配置 Fastify 适配器而不是 Express。

ts 复制代码
// main.ts
import { 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 适配器相同。

AdonisJS

AdonisJS 的 App 代码是通过其 CLI 生成的。这里只展示若干相关文件。

ts 复制代码
// server.ts
import '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.ts
import 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 框架是哪一个?

欢迎在本文下方自由言论,文明共享。谢谢大家的点赞,掰掰~

《前端猫猫教》每日 9 点半更新,坚持阅读,自律打卡,每天一次,进步一点

相关推荐
我命由我12345几秒前
微信小程序 - 页面返回并传递数据(使用事件通道、操作页面栈)
开发语言·前端·javascript·微信小程序·小程序·前端框架·js
一水鉴天几秒前
整体设计 定稿 备忘录仪表盘方案 之1 初稿之8 V5版本的主程序 之2: 自动化导航 + 定制化服务 + 个性化智能体(豆包助手)
前端·人工智能·架构
vortex512 分钟前
【Web开发】从WSGI到Servlet再到Spring Boot
前端·spring boot·servlet
于谦15 分钟前
git提交信息也能自动格式化了?committier快速体验
前端·javascript·代码规范
小高00718 分钟前
React 避坑指南:彻底搞定不必要的重新渲染
前端·javascript·react.js
浩浩酱23 分钟前
【TS】any的问题及与unknown的区别
前端·typescript
San30.23 分钟前
从原型链到“圣杯模式”:JavaScript 继承方案的演进与终极解法
开发语言·javascript·原型模式
dagouaofei23 分钟前
手术室护理年终PPT怎么做?
前端·python·html·powerpoint
技术爬爬虾23 分钟前
为什么React的漏洞能攻破服务器?Next.js与RSC入门基础
前端·数据库·安全
JS_GGbond24 分钟前
浏览器三大核心API:LocalStorage、Fetch API、History API详解
前端·javascript