1、使用最新版本的 Node.js
仅仅是简单的升级 Node.js 版本就可以轻松地获得性能提升,因为几乎任何新版本的 Node.js 都会比老版本性能更好,为什么?
Node.js 每个版本的性能提升主要来自于两个方面:
- V8 的版本更新;
- Node.js 内部代码的更新优化。
例如最新的 V8 7.1 中,就优化了某些情形下闭包的逃逸分析,让 Array 的一些方法得到了性能提升:
![06dcee76c5e62ef9855ca847395f1bcf.png](https://img-blog.csdnimg.cn/img_convert/06dcee76c5e62ef9855ca847395f1bcf.png)
Node.js 的内部代码,随着版本的升级,也会有明显的优化,比如下面这个图就是 require 的性能随着 Node.js 版本升级的变化:
![776f05d7647631f3dcf5c92fe219bee8.png](https://img-blog.csdnimg.cn/img_convert/776f05d7647631f3dcf5c92fe219bee8.png)
每个提交到 Node.js 的 PR 都会在 review 的时候考虑会不会对当前性能造成衰退。同时也有专门的 benchmarking 团队来监控性能变化,你可以在这里看到 Node.js 的每个版本的性能变化。
所以,你可以完全对新版本 Node.js 的性能放心,如果发现了任何在新版本下的性能衰退,欢迎提交一个 issue。
如何选择 Node.js 的版本?
这里就要科普一下 Node.js 的版本策略:
- Node.js 的版本主要分为 Current 和 LTS;
- Current 就是当前最新的、依然处于开发中的 Node.js 版本;
- LTS 就是稳定的、会长期维护的版本;
- Node.js 每六个月(每年的四月和十月)会发布一次大版本升级,大版本会带来一些不兼容的升级;
- 每年四月发布的版本(版本号为偶数,如 v10)是 LTS 版本,即长期支持的版本,社区会从发布当年的十月开始,继续维护 18 + 12 个月(Active LTS + Maintaince LTS);
- 每年十月发布的版本(版本号为奇数,例如现在的 v11)只有 8 个月的维护期。
举个例子,现在(2018年11月),Node.js Current 的版本是 v11,LTS 版本是 v10 和 v8。更老的 v6 处于 Maintenace LTS,从明年四月起就不再维护了。去年十月发布的 v9 版本在今年六月结束了维护。
![1547a3d5cedd4d2285520c932957bb2c.png](https://img-blog.csdnimg.cn/img_convert/1547a3d5cedd4d2285520c932957bb2c.png)
对于生产环境而言,Node.js 官方推荐使用最新的 LTS 版本,现在是 v10.13.0。
2、使用 fast-json-stringify 加速 JSON 序列化
在 JavaScript 中,生成 JSON 字符串是非常方便的:
const json = JSON.stringify(obj)
但很少人会想到这里竟然也存在性能优化的空间,那就是使用 JSON Schema 来加速序列化。
在 JSON 序列化时,我们需要识别大量的字段类型,比如对于 string 类型,我们就需要在两边加上 ",对于数组类型,我们需要遍历数组,把每个对象序列化后,用 , 隔开,然后在两边加上 [ 和 ],诸如此类等等。
但如果已经提前通过 Schema 知道每个字段的类型,那么就不需要遍历、识别字段类型,而可以直接用序列化对应的字段,这就大大减少了计算开销,这就是 fast-json-stringfy 的原理。
根据项目中的跑分,在某些情况下甚至可以比 JSON.stringify 快接近 10 倍!
![af2a65955587ee50619dd9c7664defe2.png](https://img-blog.csdnimg.cn/img_convert/af2a65955587ee50619dd9c7664defe2.png)
一个简单的示例:
const fastJson = require('fast-json-stringify')const stringify = fastJson({ title: 'Example Schema', type: 'object', properties: { name: { type: 'string' }, age: { type: 'integer' }, books: { type: 'array', items: { type: 'string', uniqueItems: true } } }})console.log(stringify({ name: 'Starkwang', age: 23, books: ['C++ Primier', '響け!ユーフォニアム~']}))//=> {"name":"Starkwang