A reaction time test looks simple: wait for a color change, then click. Behind the result are a timer, browser rendering, input events, and measurement limits.
VoltReflex is our free browser-based visual reaction test. This article explains the general ideas behind a test like it; the example below is illustrative, not VoltReflex’s production code.
The basic sequence
- Start a trial and wait for a random delay.
- Show a visual signal and record a timestamp.
- When the player responds, record a second timestamp.
- Subtract the first timestamp from the second and repeat across multiple trials.
Randomizing the delay makes it harder to predict the signal. A response before the signal should be treated as a false start, rather than a fast result.
A small JavaScript example
This example assumes a button with id "test" and an element with id "result". Click once to start, then again after it turns green.
const button = document.querySelector('#test');
const result = document.querySelector('#result');
let state = 'idle';
let startedAt = 0;
let timer;
button.addEventListener('click', () => {
if (state === 'idle') {
state = 'waiting';
button.style.background = 'orange';
result.textContent = 'Wait for green...';
timer = setTimeout(() => {
button.style.background = 'green';
startedAt = performance.now();
state = 'ready';
}, 1500 + Math.random() * 3500);
} else if (state === 'waiting') {
clearTimeout(timer);
state = 'idle';
button.style.background = '';
result.textContent = 'Too early. Click to try again.';
} else {
const elapsed = performance.now() - startedAt;
state = 'idle';
button.style.background = '';
result.textContent = 'Response: ' + elapsed.toFixed(0) + ' ms. Click to retry.';
}
});
This is a teaching example, not a complete production implementation. A real test should handle keyboard and touch input accessibly, prevent accidental repeated events, reset state cleanly and report multiple rounds.
Timer precision is not end-to-end accuracy
performance.now() is a monotonic clock suitable for measuring elapsed time. But setting a CSS color does not mean the new pixels are visible at that exact instant. The browser still has to render a frame, the display must refresh, and the input event has its own path through hardware and the operating system. Main-thread work can also delay callbacks or event handling.
At 60 Hz, one refresh interval is about 16.7 ms; at 144 Hz it is about 6.9 ms. These are frame intervals, not a complete measurement of display latency. High-resolution timestamps cannot remove delays elsewhere in the chain.
Make results more useful
- Record several trials and show the average alongside individual scores.
- Explain false starts and allow retries.
- Compare sessions on the same device, browser and input method.
- Avoid presenting browser results as clinical measurements or precise comparisons across different hardware.
- Keep the interface usable with a keyboard and provide feedback that does not rely on color alone.
For a ready-to-use example, try VoltReflex and compare its multi-round results on the same setup. A single number is interesting; a consistent method makes it more meaningful.
This article was prepared with AI assistance.
Top comments (0)