• home > webfront > server > Fastify >

    为什么入坑Fastify:性能最好的 nodejs 框架?

    Author:zhoulujun Date:

    Fastify :性能最好的 nodejs 框架?对于nodejs项目,一般小型会用express,中大的用nestjs(核心是IOC、AOP、模块化设计)——TS人称小

    Fastify :性能最好的 nodejs 框架?

    对于nodejs项目,一般小型会用express,中大的用nestjs(核心是IOC、AOP、模块化设计)——TS人称小Java,Nest人称小Spring

    Express 内置常用的插件,开箱即用,像静态资源、路由、文件上传下载、json解析等,此外他的 req和res继承自 nodejs标准库,减少学习成本

    Express只是一个纯路由库, 大多数内容还是要去找社区的middleware.。而这些项目太老,很多实现现在看来不是很高效。很多cjs格式的库也不便于treeshake.

    Koa作为Express的升级版(是由Express的创始人编写的,它专注于使用异步函数来处理HTTP请求和响应。它使用ES6语法,具有更少的代码和更简单的中间件体系结构),问题是同样的!

    Fastify 类似 express 内置了更多功能,例如基于json schema的参数检验和json序列化。

    In Fastify everything is a plugin. 卖点是扩展性好、速度快,是 Express、Koa 的竞品。

    他比Express的优势就是:Fastify是一个快速、低开销的Web框架,它旨在提供最佳的性能

    Fastify v3 取得了非常成功的成绩(每个月的下载量已经超过了一百万,并且还在上升)

    v2-bc083d232bc0f1a1b733aaa405e7a43d_720w.webp

    官方宣称Fastify v4号称地表最快(目前性能最好的 nodejs 框架)!



    使用起来非常简单

    import Fastify from 'fastify'
    
    const app = Fastify({ logger: true })
    
    app.get('/', async (request, reply) => {
      setImmediate(() => {
        reply.send({ hello: 'world' })
      })
      // return reply is needed to tell Fastify we will call
      // reply.send() in the future.
      return reply
    })
    app.post('/user/:id', {
      schema: {
        params: {
          type: 'object',
          properties: {
          	id: { type: 'number' }
          }
        },
        response: {
          // 2xx 表示 200~299 的状态都适用此 schema
          '2xx': {
            type: 'object',
            properties: {
              id: { type: 'number' },
              name: { type: 'string' }
            }
          }
        }
      }
    }, async (req) => {
      const id = req.params.id
      const userInfo = await User.findById(id)
      // Content-Type 默认为 application/json
      return userInfo
    })
    
    await app.listen({ port: 3000 })

    让 fastify 性能提升的的秘诀在于,其返回 application/json 类型数据的时候,并没有使用原生的 JSON.stringify,而是自己内部重新实现了一套 JSON 序列化的方法,这个 schema 就是 JSON 序列化性能翻倍的关键。

    fastify 之所以号称自己快,得益于fastify/fast-json-stringify 、find-my-way、@fastify/middie等库,当然内部还有一些其他的优化方,下面大致讲解一下

    fastify为什么这么快

    Decorators

    例如弱类型系统的编程语言不会提前给对象的成员布局内存,因此在给对象赋值上不同类型的成员时会产生性能问题。像是fastify为了优化FastifyInstance实例的性能,需要提前给对象赋值对应类型的非undefined的值,例如你向往Fastify对象上挂载一个db_conn_uri的字符串,需要在初始化阶段先给这个对象赋值为''空字符串,然后再其它生命周期中给他赋值有意义的值。

    https://fastify.dev/docs/latest/Reference/Decorators

    同样是类型系统的原因,JSON.parse无法在反序列化阶段立即发现类型错误,需要引入ajv等json schema校验库。不过由于ajv本身还不是语言层面的优化,因此涉及到browser环境,冷启动代码的时候ajv需要有一个初始化编译json schema环节,在客户端环境下(包括browser,react native,electron等)也会冲击性能,服务器端的话其实还好,因为服务器端其实对冷启动速度不太care,可是node.js也不只是运行在服务端啊,现在那么多EXE都用electron写了。而JSON.stringify也无法充分利用类型信息来优化JSON序列化的执行路径,需要借助fastify/fast-json-stringify 提前通过json schema来告知JSON序列化器一些相关的类型信息,以便优化性能。

    预编译的序列化

    在发送响应之前,Fastify不是在运行时动态序列化对象,而是使用预编译的序列化函数。这种方法减少了每个请求的处理时间,因为响应可以更快地被序列化并发送给客户端。

    模式驱动的开发

    Fastify强烈推荐(并在某些情况下要求)使用JSON Schema来定义路由的输入和输出。这不仅有助于验证和文档化API,而且允许Fastify预编译验证逻辑,从而提高运行时效率。

    高效的路由分发机制

    Fastify使用了一个非常快的路由分发机制。

    Fastify 使用了树状的路由匹配算法,将路由组织成类似树结构(Prefix Tree),这使得它在路由匹配时能够快速定位到目标路由,比线性搜索要快得多。对于嵌套、动态路由,它也能保证查询效率。

    具体可以阅读:

    相比之下,Express 的路由匹配是顺序查找(先定义的路由优先),当路由数量较多时性能会下降。

    当请求进来时,它能够迅速决定哪个处理函数应该被调用,这种快速的路由决策极大地减少了请求处理时间。

    此外,Fastify还使用了基于正则表达式的路由解析器,允许更快地匹配和处理HTTP请求,比一些依赖字符串分割的方法更高效。


    高效的日志记录

    内置的日志记录工具 Pino 是为速度而设计的,它提供了极低的开销日志记录功能,这对于保持应用程序的性能至关重要。



    转载本站文章《为什么入坑Fastify:性能最好的 nodejs 框架?》,
    请注明出处:https://www.zhoulujun.cn/html/webfront/server/Fastify/9300.html