Skip to main content

JavaScript Performance

JavaScript Performance Measurement

Written by Published

performance.now gives a far more precise timestamp than Date.now for measuring code.

Date.now() only has millisecond precision and can jump if the clock changes.

performance.now() is designed specifically for timing code.

Example

Example

javascript

const started = performance.now();

let total = 0;
for (let i = 0; i < 10000; i++) {
  total += i;
}

const elapsed = performance.now() - started;

console.log(typeof elapsed);
console.log(elapsed >= 0);

performance.now() returns a decimal number of milliseconds.

Measuring Precisely

performance.now() returns milliseconds, with a fractional part.

It always increases, unlike the system clock, which can be adjusted.

console.time and console.timeEnd wrap the same idea conveniently.

Syntax

Syntax

javascript

const start = performance.now();
// work
const duration = performance.now() - start;

The result is relative time, not a calendar date.

Timing a Block of Code

The pattern is always the same: read the clock, do the work, subtract.

Example

Example

javascript

function timeIt(fn) {
  const start = performance.now();
  fn();
  return performance.now() - start;
}

const duration = timeIt(function () {
  let total = 0;
  for (let i = 0; i < 50000; i++) {
    total += i;
  }
});

console.log(duration >= 0);
console.log(typeof duration);

A reusable timeIt helper avoids repeating the pattern everywhere.

Comparing Two Approaches

Timing both the same way is the only fair comparison.

Example

Example

javascript

function timeIt(fn) {
  const start = performance.now();
  fn();
  return performance.now() - start;
}

const numbers = Array.from({ length: 1000 }, function (_, i) { return i; });

const loopTime = timeIt(function () {
  let total = 0;
  for (const n of numbers) { total += n; }
});

const reduceTime = timeIt(function () {
  numbers.reduce(function (sum, n) { return sum + n; }, 0);
});

console.log(loopTime >= 0 && reduceTime >= 0);

For small arrays the difference is rarely worth worrying about.

console.time and console.timeEnd

A convenient shortcut that logs the duration under a label.

Example

Example

javascript

console.time("counting");

let total = 0;
for (let i = 0; i < 10000; i++) {
  total += i;
}

console.timeEnd("counting");
console.log(typeof total);

The timing itself is printed with the label automatically.

Run It More Than Once

A single measurement can be noisy.

Running several times and comparing gives a more reliable picture.

Example

Example

javascript

function timeIt(fn) {
  const start = performance.now();
  fn();
  return performance.now() - start;
}

const durations = [];
for (let i = 0; i < 3; i++) {
  durations.push(timeIt(function () {
    let total = 0;
    for (let j = 0; j < 10000; j++) { total += j; }
  }));
}

console.log(durations.length);
console.log(durations.every(function (d) { return d >= 0; }));

Three measurements give a better sense of the typical cost.

Measure in the Real Environment

A fast development machine can hide a slowdown a visitor's device would feel.

Numbers from real devices, or at least a throttled test, matter more than a quick local check.

Example

Example

javascript

console.log("always confirm timing on a realistic device, not just a fast laptop");

Browser developer tools include CPU throttling for exactly this reason.

Complete Example

Complete Example

html

<!DOCTYPE html>
<html>
<head>
  <title>JavaScript Performance Measurement</title>
</head>
<body>

  <h1>Measuring Performance</h1>

  <p id="out"></p>

  <script>
    function timeIt(fn) {
      const start = performance.now();
      fn();
      return performance.now() - start;
    }

    const duration = timeIt(function () {
      let total = 0;
      for (let i = 0; i < 1000000; i++) {
        total += i;
      }
    });

    document.getElementById("out").textContent =
      "That loop took " + duration.toFixed(2) + "ms";
  </script>

</body>
</html>

Try It Yourself

Run the above example in the Try It Editor.

Try a bigger loop:

Raise the count tenfold and see the time grow roughly in proportion.

Important Points

  • performance.now() is precise and always increasing.
  • Subtracting a start time from an end time measures a duration.
  • console.time and console.timeEnd are a convenient shortcut.
  • Run a measurement more than once to see past noise.
  • Confirm timing on a realistic device, not just a fast machine.

Conclusion

Precise measurement is what turns performance work from guessing into engineering.

The pattern is always the same three lines, wherever you use it.

Every technique earlier in this section should be justified by a measurement like this.