A metronome is, by essence, something that needs to have very precise scheduling.
The web is an environment where precise scheduling is often challenging, and increasingly so with the security mitigations put in place since the publication of Spectre/Meltdown.
But what if we could use the Web Audio API differently to do most of the work
for us, so we can forget about clock domains,
setTimeout throttle in the
background, Workers, and all that?
This tutorial will serve as an example of a more general Web Audio API advice: don’t use the main thread if you don’t have to: you can’t predict how much it is doing. It’s hard enough to keep it under control in your own app, and it’s borderline impossible is you happen to write a library that is going to be used by a number of people to do various things that you didn’t anticipate.
The metronome shown here is extremely robust, it can be tested here. It will never glitch or drift or have any jitter or anything except in case of bugs in the Web Audio API implementation. Which is certainly something that can happen (I’ve certainly written my fair share of those in Firefox).
A similar technique can be applied to other audio programs: connecting audio
AudioParams in the Web Audio API is a good way to have very robust
parameter changes even under load. Under normal circumstances, the real-time
thread on which the Web Audio API does its processing will not be preempted by
other thread, and its scheduling will be really precise.
Of course, for apps that need a lot of interactivity, the main thread load will still be a factor, but when it’s possible to not use it, it’s always better to do so.