I've noticed a strange behavior of the performance of the following code in node.js. When the size of content
is 1.4KB, the response time of the request is roughly 16ms. However, when the size of content
is only 988 bytes, the response time of the request is strangely much longer, roughly 200ms:
response.writeHead(200, {"Content-Type": "application/json"});
response.write(JSON.stringify(content, null, 0));
response.end();
This does not seem intuitive. Looking into Firebug's net tab, the increase/difference all comes from receiving (waiting on the other hand is 16ms for both).
I've made the following change to fix it so that both cases have 16ms response time:
response.writeHead(200, {"Content-Type": "application/json"});
response.end(JSON.stringify(content, null, 0));
I've looked through node.js doc but so far haven't found related info. My guess this is related to the buffering, but could node.js preempt between write()
and end()
?
Update:
This was tested on v0.10.1 on Linux.
I tried to peek into source and have identified the difference between the 2 path. The first version has 2 Socket.write calls.
writeHead(...)
write(chunk)
chunk = Buffer.byteLength(chunk).toString(16) + CRLF + chunk + CRLF;
ret = this._send(chunk);
this._writeRaw(chunk);
this.connection.write(chunk);
end()
ret = this._send('0\r\n' + this._trailer + '\r\n'); // Last chunk.
this._writeRaw(chunk);
this.connection.write(chunk);
The second, good version has just 1 Socket.write call:
writeHead(...)
end(chunk)
var l = Buffer.byteLength(chunk).toString(16);
ret = this.connection.write(this._header + l + CRLF +
chunk + '\r\n0\r\n' +
this._trailer + '\r\n', encoding);
Still not sure what makes the first version not working well with smaller response size.