Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Performance difference between res.json() and res.end()

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?

like image 435
George Eracleous Avatar asked Apr 02 '14 15:04

George Eracleous


People also ask

What is difference between RES JSON and res?

res. json forces the argument to JSON. res. send will take an non-json object or non-json array and send another type.

What is the difference between Res send and res end?

res. send() is used to send the response to the client where res. end() is used to end the response you are sending.

Why do we use res JSON ()?

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.

What res end () does?

end() Function. The res. end() function is used to end the response process. This method actually comes from the Node core, specifically the response.


1 Answers

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:

  • Supports HEAD requests
  • Sets the appropriate Content-Length header to ensure that the response does not use Transfer-Encoding: chunked, which wastes bandwidth.
  • Most importantly, provides ETag support automatically, allowing conditional GETs.

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.

like image 61
josh3736 Avatar answered Sep 25 '22 07:09

josh3736