I want to send a JSON response using Node and Express. I'm trying to compare the performance of res.end
and res.json
for this purpose.
Version 1: res.json
res.json(anObject);
Version 2: res.end
res.setHeader('Content-Type', 'application/json');
res.end(JSON.stringify(anObject));
Running some benchmarks I can see that the second version is almost 15% faster than the first one. Is there a particular reason I have to use res.json
if I want to send a JSON response?
res. json forces the argument to JSON. res. send will take an non-json object or non-json array and send another type.
res. send() is used to send the response to the client where res. end() is used to end the response you are sending.
json() Function. The res. json() function sends a JSON response. This method sends a response (with the correct content-type) that is the parameter converted to a JSON string using the JSON.
end() Function. The res. end() function is used to end the response process. This method actually comes from the Node core, specifically the response.
Yes, is is very desirable to use json
despite the overhead.
setHeader
and end
come from the native http module. By using them, you're effectively bypassing a lot Express's added features, hence the moderate speed bump in a benchmark.
However, benchmarks in isolation don't tell the whole story. json
is really just a convenience method that sets the Content-Type
and then calls send
. send
is an extremely useful function because it:
HEAD
requestsContent-Length
header to ensure that the response does not use Transfer-Encoding: chunked
, which wastes bandwidth.ETag
support automatically, allowing conditional GET
s.The last point is the biggest benefit of json
and probably the biggest part of the 15% difference. Express calculates a CRC32 checksum of the JSON string and adds it as the ETag
header. This allows a browser making subsequent requests for the same resource to issue a conditional GET
(the If-None-Match
header), and your server will respond 304 Not Modified
if the JSON string is the same, meaning the actual JSON need not be sent over the network again.
This can add up to substantial bandwidth (and thus time) savings. Because the network is a much larger bottleneck than CPU, these savings are almost sure to eclipse the relatively small CPU savings you'd get from skipping json()
.
Finally, there's also the issue of bugs. Your "version 2" example has a bug.
JSON is stringified as UTF-8, and Chrome (contrary to spec) does not default to handling application/json
responses as UTF-8; you need to supply a charset
. This means non-ASCII characters will be mangled in Chrome. This issue has already been discovered by Express users, and Express sets the proper header for you.
This is one of the many reasons to be careful of premature/micro-optimization. You run the very real risk of introducing bugs.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With