res.json()和res.end()之间的性能差异
我想用Node和Express发送一个JSON响应。 我试图比较res.end
和res.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
是非常可取的。
setHeader
和end
来自本地http模块 。 通过使用它们,您可以有效地绕开Express的许多附加function,因此可以在基准testing中实现中等的速度。
但是,孤立的基准并不能说明整个故事。 json
实际上只是一个设置 Content-Type
然后调用send
的简便方法。 send
是一个非常有用的function,因为它:
- 支持
HEAD
请求 - 设置适当的
Content-Length
头,以确保响应不使用Transfer-Encoding: chunked
,这会浪费带宽。 - 最重要的是,自动提供
ETag
支持,允许有条件的GET
。
最后一点是json
的最大好处,可能是15%差距的最大部分。 Express计算JSONstring的CRC32校验和,并将其添加为ETag
头。 这就允许浏览器对同一资源的后续请求发出条件GET
( If-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为您设置了正确的标题。
这是小心过早/微观优化的众多原因之一。 你运行引入错误的真正风险。