为什么入坑Fastify:性能最好的 nodejs 框架?
Author:zhoulujun Date:
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 取得了非常成功的成绩(每个月的下载量已经超过了一百万,并且还在上升)
官方宣称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),这使得它在路由匹配时能够快速定位到目标路由,比线性搜索要快得多。对于嵌套、动态路由,它也能保证查询效率。
具体可以阅读:
Node.js 服务性能翻倍的秘密(二) https://juejin.cn/post/6911113668050550792
Fastify 的高性能路由秘密:揭开 Radix-Trie 的面纱 https://www.bytezonex.com/archives/bpiM8oI4.html
相比之下,Express 的路由匹配是顺序查找(先定义的路由优先),当路由数量较多时性能会下降。
当请求进来时,它能够迅速决定哪个处理函数应该被调用,这种快速的路由决策极大地减少了请求处理时间。
此外,Fastify还使用了基于正则表达式的路由解析器,允许更快地匹配和处理HTTP请求,比一些依赖字符串分割的方法更高效。
高效的日志记录
内置的日志记录工具 Pino 是为速度而设计的,它提供了极低的开销日志记录功能,这对于保持应用程序的性能至关重要。
转载本站文章《为什么入坑Fastify:性能最好的 nodejs 框架?》,
请注明出处:https://www.zhoulujun.cn/html/webfront/server/Fastify/9300.html