Timing in JavaScript

There are some tasks on the frontend that require time measurement, such as calculating the load time of an external resource, or calculating the animation progress.

The temptation to use Date.now is huge:

const start = Date.now();
const result = await fetch('/data');

console.log('Elapsed time in milliseconds:', Date.now() - start);

Looks like the problem is solved, and you can go grab some coffee. Here is the thing: the duration calculated this way may turn out to be negative.

What’s wrong with Date.now?

The main problems of the Date.now function in the context of our task are as follows:

  1. Date.now is not monotonic, meaning, it can both increase and decrease (which leads to negative duration in calculations).
  2. It does not guarantee uniform growth of returned values.

The root of these problems is that Date and its functions use a system clock that is affected by external influences:

What to use instead of Date.now?

In the browser

The High Resolution Time specification describes performance.now function, which not only solves the stated problems, but also increases the accuracy of measurements to microseconds (depending on browser). For details see the specification or MDN.

In Node.js

Node.js provides process.hrtime and process.hrtime.bigint functions that also don’t depend on the system clock and increase the accuracy to nanoseconds.