Web Audio API vs. Standard Timers (Why Your Metronome Wobbles)
The problem with "normal timers"
In JavaScript you might see code like:
setInterval(...)setTimeout(...)- animation loops
These timers are fine for many things. But they are not built for musical timing.
Why?
Because the browser can delay them when:
- the CPU is busy
- the tab is in the background
- the laptop is saving power
- the page is doing heavy UI work
When a timer fires late, the metronome click is late. That creates jitter.
Why jitter matters musically
Humans can hear small timing problems in a click:
- At 120 BPM you expect clicks every 500 ms.
- If one click arrives 20–30 ms late, you feel it.
Over time, unevenness makes practice frustrating because you're trying to lock in time, but the metronome itself isn't stable.
Web Audio solves a different problem
Web Audio is designed for sound. The key difference is:
You can schedule sounds for an exact time in the future.
That means:
- your code does not have to "wake up" at the exact moment
- you only need to schedule ahead
- the audio engine plays at the correct time
So Web Audio gives you less jitter.
The best setup (simple version)
A strong browser metronome typically uses:
- AudioContext time as the master clock
- A small scheduler loop that stays ahead by 100–200 ms
- Clicks generated by AudioWorklet (best) or prebuilt click buffers
The scheduler loop can run on the main thread or in a Web Worker. But the worker is not "more accurate." It just reduces UI-related delays.
What happens when the tab goes to the background
Browsers may:
- slow down timers
- pause them
- suspend audio until the user interacts again
A pro web metronome should:
- detect this
- show a clear message if audio is paused by the browser
- resume cleanly when the user presses Play again
Bottom line
If a web metronome uses standard timers to "play the click right now," it will wobble sooner or later.
If it schedules clicks on the Web Audio timeline, it can be stable enough for serious practice.