🔧 Programmierung 🕛 vor 5 Monaten 4 Min Lesezeit
0

Building a Reliable Browser Stopwatch Is Harder Than You Think

↗ Quelle (dev.to)
🗣️ Stimme:
📑 Inhaltsübersicht

I needed a simple stopwatch in the browser for timing user interaction flows during usability testing. I thought it would take 10 minutes to build. It took two days to get right, and the reason is that JavaScript timers are fundamentally unreliable for precision timing.






The problem with setInterval



The naive approach is obvious:




CODE
let elapsed = 0;
const interval = setInterval(() => {
elapsed += 10;
display(elapsed);
}, 10);






This looks like it increments every 10 milliseconds. It does not. setInterval guarantees a minimum delay of 10ms, not an exact delay. The actual interval depends on the browser's event loop, current tab focus state, CPU load, and garbage collection pauses.



On a busy page, a "10ms" interval might fire every 14-20ms. Over 60 seconds, that drift accumulates to several seconds of error. Your stopwatch shows 60 seconds, but 63 seconds have actually passed.






The correct approach: wall clock timestamps



Instead of counting intervals, you record the start time and compute elapsed time on every tick:




CODE
const startTime = performance.now();

function update() {
const elapsed = performance.now() - startTime;
display(elapsed);
requestAnimationFrame(update);
}
requestAnimationFrame(update);






performance.now() gives you a high-resolution timestamp that is not affected by system clock adjustments. Date.now() works too, but it is only millisecond-precision and can jump if the system clock is adjusted.



Using requestAnimationFrame instead of setInterval ties your display updates to the screen refresh rate (typically 60Hz), which is sufficient for a visual display and more efficient than hammering the DOM every 10ms.






The background tab problem



When a browser tab is in the background, most browsers throttle timers aggressively. setInterval might fire only once per second. requestAnimationFrame stops entirely.



For a stopwatch, this is a critical issue. You start the timer, switch to another tab, come back, and the display is behind.



The fix is straightforward with the wall-clock approach: when the tab regains focus, you simply recalculate elapsed time from the original start timestamp. The display catches up instantly.




CODE
document.addEventListener('visibilitychange', () => {
if (!document.hidden) {
update(); // Recalculate from startTime
}
});









Lap times and split tracking



A stopwatch without lap functionality is barely useful for real timing work. The implementation is simple: on each lap, record the current elapsed time. Display both the total elapsed time and the delta from the previous lap.




CODE
const laps = [];

function recordLap() {
const current = performance.now() - startTime;
const previous = laps.length > 0 ? laps[laps.length - 1] : 0;
laps.push(current);
displayLap(current, current - previous);
}






The UX details matter more than the code. Fastest and slowest laps should be highlighted. The lap list should auto-scroll but allow the user to scroll back without fighting the auto-scroll. Export to CSV is essential for any serious timing work.






Pause and resume without drift



Pausing introduces another subtle bug opportunity. If you just store the elapsed time at pause and restart the clock, you need to offset the start time:




CODE
let pauseOffset = 0;
let pauseStart = null;

function pause() {
pauseStart = performance.now();
}

function resume() {
pauseOffset += performance.now() - pauseStart;
pauseStart = null;
}

function getElapsed() {
const now = pauseStart || performance.now();
return now - startTime - pauseOffset;
}






This ensures that paused time is not counted toward elapsed time, regardless of how long the pause lasts.






Why I built a web-based stopwatch



Phone stopwatches work fine for casual timing. But for development work -- timing API calls, user flows, build processes -- I want the timer on the same screen I am working on, with keyboard shortcuts, lap tracking, and the ability to copy results.



I built one at zovo.one/free-tools/stopwatch that handles all the edge cases: accurate wall-clock timing, background tab resilience, lap tracking with highlights, keyboard controls, and clean data export. It is the stopwatch I wished existed the first time I tried to time a user session.



I'm Michael Lip. I build free developer tools at zovo.one. 500+ tools, all private, all free.

Vollständiger Original-Artikel
Den kompletten Beitrag mit allen Details direkt auf dev.to lesen.
↗ Original-Artikel auf dev.to lesen
Wie bewertest du diesen Beitrag?
1 Klick Feedback
Teilen mit Netzwerk & Team:

Community-Analysen & Experten-Meinungen 0

Verfasse deine eigene Analyse, teile Workarounds oder diskutiere diesen Vorfall im Blog.
Noch keine Community-Analyse verfasst. Markiere einen Textabschnitt oder klicke oben auf Eigene Analyse verfassen“!
Community Pulse: Relevanz-Einschätzung
1 Klick Experten-Votum
🔴 Akute Relevanz 0%
🟡 In Evaluierung 0%
🟢 Keine Auswirkung 0%
Spannende Innovation 0%
Verwandte Story-Cluster & Quellen (Vektor-KI)
Port 8095 Engine
1 Quelle
Razer's new Tartarus V2 Pro is the weirdest gaming keyboard I've ever wanted, loaded with fancy switches and ergonomic relief
1 Quelle
HMX 6 mit Cortana-KI auf der zweiten RTX 5090 – Rückblick auf die HMX Pro
1 Quelle
Huawei ist gelungen, wovon Smartphone-Besitzer seit Jahren träumen
Ähnliche Beiträge
🔍 Verwandte News

Auch interessante Nachrichten Building a Reliable Browser Stopwatch Is Harder Than You Think

Thematisch verwandte Begriffe: Building, Reliable, Browser, Stopwatch · 6 Treffer

Laden...

Videos werden geladen ...

Laden...

Beiträge werden geladen ...

Laden...

Videos werden geladen ...

Laden...

Beiträge werden geladen ...

Laden...

Videos werden geladen ...

Laden...

Beiträge werden geladen ...

Laden...

Videos werden geladen ...

Laden...

Beiträge werden geladen ...

Laden...

Videos werden geladen ...