2

I am trying to measure the time an asynchronous http request is processed by an http server developed in nodejs. By that I mean the time from which the server informs the client starting to process the request, to the time the server finishes processing and returns the response back to the client.

So, accrding to XMLHttpRequest documentation for readyState I am under the impression that the time difference between when readyState == 3 to readyState == 4 gets me what I want. In practice I get almost 0 to be the time difference between the two. However my expectation, according to the code snippets below is to get something around to 2000+ ms.

Why is that and how can I roughly measure the processing time in practice?

Client side:

<script>
    let begin;
    const xhttp = new XMLHttpRequest();
    xhttp.open("GET", "https://mydomain. com/API", true);
    xhttp.send();
    xhttp.onreadystatechange = function () {
        if (this.readyState == 3) {
            begin = Date.now();
        }

        if (this.readyState == 4 && this.status == 200) {
            console.log("Execution time (ms):" + (Date.now() - begin));
        }
    };
</script>

server side ( as seen, processing a request takes around 2000ms)

let http = require('http');
let url = require('url');
let server = http.createServer(function (req, res) {
    reqReceived++;
    let q = url.parse(req.url, true);
    res.writeHead(200, {
        "Content-Type": "text/html",
        "Access-Control-Allow-Origin": "*"
    });
    setTimeout(() => {
        res.end(`response is ready`);
     }, 2000);

});
server.listen();

You might argue that I should have put writing the head inside the timeout callback, however it would not still make any time difference for the client to receive readyState ==3 and == 4.

C graphics
  • 7,308
  • 19
  • 83
  • 134
  • Curious, are you developing a web app/page? If so, does Dev Tools' Waterfall data give you what you want? – randy Apr 05 '22 at 17:10
  • [TTFB analysis](https://stackoverflow.com/a/52770802/2834978) and [chrome queue request](https://stackoverflow.com/a/68734995/2834978). Might give you ideas to debug. Also [TTFB on nginx](https://stackoverflow.com/a/68402917/2834978) – LMC Apr 07 '22 at 22:35

4 Answers4

3

The right readyState to start your timer is 1. Node.JS will send headers only when you call res.end(response is ready);

I tried your code and scan it using Wireshark: screenshot

The row #4 corresponding to the request sent by your client. The #6 is the header is sent by your server with the body.

According to MDN:

  • state 2 => XHR received headers from server
  • state 3 => Response is being loaded (if chunk)
  • state 4 => Response parsed.

By testing 2, 3 or 4, you'll only test the time that XHR will process the response. But "response is ready" is very short and it explain why you got 0ms everytime.

Romain V...
  • 423
  • 2
  • 10
0

You can use the following code

  var xhttp = new XMLHttpRequest();
  xhttp.onreadystatechange = function() {
    if(this.readyState == 1) console.time("count");
    if (this.readyState == 4 && this.status == 200) {
      console.timeEnd("count");
    }
  };
  xhttp.open("GET", "https://mydomain. com/API", true);
  xhttp.send();
}

With this, you can check the time after the request has been opened. If you want to count the total time you can move the console.time before the open function call, and you can see on the network tab (chrome browser) that the timing is near the actual timing the browser counts.

  var xhttp = new XMLHttpRequest();
  xhttp.onreadystatechange = function() {
    if (this.readyState == 4 && this.status == 200) {
      console.timeEnd("count");
    }
  };
  console.time("count");
  xhttp.open("GET", "https://mydomain. com/API", true);
  xhttp.send();
}

Note: if you get near 0ms for your request make sure you have disabled the cache of your request from the network tab

prieston
  • 1,426
  • 2
  • 18
  • 39
-1

From MDN, readyState = 3 means Response's body is being received. Which I interpret as the request has already processed and the client is now downloading the response.

To achieve what you want I would suggest measure the time difference from when you send the request, just above xhttp.send(), and when the readyState is 3. If it was me, I would extend it to when readyState is 4. This gives more realistic times which an end user might experience and includes the time it takes for the request to go over the network.

As a side note may be try measuring the difference between readyState=2 and readyState=4. Per MDN docs readyState is 2 when the request has been sent and the client has received the headers back, which means the connection has been successful. So, it should give accurate representation of time spent during processing on server side and will eliminate any network delays.

I would love to know your results.

arbghl
  • 358
  • 2
  • 14
  • None of that helps unfortunately as have already tried them, 1) from client send to the ready state 3 or 4 would include the request waiting in the queue as well. Say the server is loaded with 1000 requests where 999 of them are in the queue at the time my request is received. So for this case, it would return, depending on the number of requests already in the queue, any number greater than 2000ms, 2) Tried and the time difference is 0 "try measuring the difference between readyState=2 and readyState=4" – C graphics Apr 01 '22 at 21:24
-1

I would do something like the following:

function timeFetch() {
  let begin
  const xhttp = new XMLHttpRequest()
  xhttp.open("GET", "https://myDomain. com/API", true)
  xhttp.send()
  xhttp.onreadystatechange = function () {
    if (this.readyState == 1) {
      begin = new Date(Date.now())
    }

    if (this.readyState == 4 && this.status == 200) {
      let end = new Date(Date.now())
      console.log(
        "Execution time (ms):" + (begin.getMilliseconds() - end.getMilliseconds()))
    }
  }
}
H00dwynk
  • 1
  • 2
  • already tried . Returns 0 – C graphics Apr 01 '22 at 21:27
  • 1
    Your answer could be improved with additional supporting information. Please [edit] to add further details, such as citations or documentation, so that others can confirm that your answer is correct. You can find more information on how to write good answers [in the help center](/help/how-to-answer). – Community Apr 02 '22 at 02:51
  • Please explain your answer so we know how is works. @Cgraphics already said it didn't work. – Arnav Thorat Apr 08 '22 at 03:14