res.json()和res.end()之间的性能差异

我想用Node和Express发送一个JSON响应。 我试图比较res.endres.json的性能。

版本1:res.json

 res.json(anObject); 

版本2:res.end

 res.setHeader('Content-Type', 'application/json'); res.end(JSON.stringify(anObject)); 

运行一些基准,我可以看到第二个版本比第一个版本快了近15%。 如果我想发送一个JSON响应,是否有一个特殊的原因,我必须使用res.json

是的,尽pipe有开销,但使用json是非常可取的。

setHeaderend来自本地http模块 。 通过使用它们,您可以有效地绕开Express的许多附加function,因此可以在基准testing中实现中等的速度。

但是,孤立的基准并不能说明整个故事。 json实际上只是一个设置 Content-Type然后调用send的简便方法。 send是一个非常有用的function,因为它:

  • 支持HEAD请求
  • 设置适当的Content-Length头,以确保响应不使用Transfer-Encoding: chunked ,这会浪费带宽。
  • 最重要的是,自动提供ETag支持,允许有条件的GET

最后一点是json的最大好处,可能是15%差距的最大部分。 Express计算JSONstring的CRC32校验和,并将其添加为ETag头。 这就允许浏览器对同一资源的后续请求发出条件GETIf-None-Match头),如果JSONstring相同,则服务器将响应304 Not Modified ,这意味着不需要发送实际的JSON再次通过networking。

这可以增加相当大的带宽(从而节省时间)。 由于networking是一个比CPU更大的瓶颈,所以这些节省几乎肯定会让跳过json() CPU节省相对较less。


最后还有bug的问题。 你的“版本2”的例子有一个错误。

JSON被string化为UTF-8,而Chrome(与规范相反)并不默认以UTF-8处理application/json响应; 你需要提供一个charset 。 这意味着非ASCII字符将在Chrome中被破坏。 Express用户已经发现了这个问题,Express为您设置了正确的标题。

这是小心过早/微观优化的众多原因之一。 你运行引入错误的真正风险。