Reaction time tests look simple. Show a signal, wait for a click, subtract two timestamps. But if you have ever tried to build one, you quickly learn that the browser adds its own small delays, and those delays can blur the result.
Here are the main things worth knowing if you want a fair measurement.
Use a high resolution clock
Date.now() only gives whole milliseconds and can jump if the system clock changes. For timing, performance.now() is the better choice because it is monotonic and offers finer resolution. The MDN page on performance.now explains the details, including why browsers deliberately reduce its precision for security.
Start the clock when the pixels change
A common mistake is starting the timer the moment you change a colour in JavaScript. The screen does not update until the next frame is painted.
Using requestAnimationFrame to start timing closer to the paint helps line the clock up with what the user actually sees.
function showSignal() { box.classList.add('go'); requestAnimationFrame(() => { start = performance.now(); }); } box.addEventListener('pointerdown', () => { const ms = performance.now() - start; results.push(ms); }); Remember the hardware
On a 60 Hz display a new frame appears roughly every 16.7 milliseconds, so the signal can appear up to one frame later than your code expects. Mice, touchscreens and keyboards add their own input delay too.
None of this can be fully removed in a browser. The practical answer is consistency. Testing on the same device each time keeps comparisons fair.
Use pointerdown, not click
The click event fires after the button is released. pointerdown fires on press, which is much closer to the moment the user actually reacts.
Randomise the wait
If the signal always appears after the same delay, people learn the rhythm and start guessing. A random wait of a second or a few seconds keeps the test honest. Also catch early clicks and treat them as false starts.
Average several attempts
Single results are noisy. Collect five or more attempts, drop obvious outliers and show the average. Users get a far more meaningful number.
See it in action
For a finished example, try VoltReflex, a free browser based reaction time test. Give it a few rounds and compare your average on different devices. You may be surprised how much the hardware changes the result.
If you are building your own version, start simple, measure carefully and be honest with users about what a browser can and cannot measure.
