Building simple online metronome in 2018

I have this little SaaS app which has the ability to turn on ticking. It can tick every second.

It’s a web app, so the ticking itself is handled by javascript.

So, how do you make a primitive metronome? It’s surprisingly not so easy in the year of 2018.
Why? Because most browsers (especially mobile browsers) implement various power saving features and aggressive ads blocking strategies.
These implementations do two things:

  1. They throttle the main thread while the tab is not active
  2. They prevent video or audio autoplay after (re)load

Number one means that you cannot simply use the good old setInterval(), because the browser will change the delay in order to save computing time for other tasks.

// This won't really work when the tab is not active and visible
// The delay will slowly increase
var interval = setInterval(function(){
    play();
}, 1000);

Number two means that when you load the page, you actually need to do some direct user input event, typically click or touch.

Allright, so how can we do this

We are gonna need few things:

  1. /index.html
  2. /app.js
  3. /Worker.js
  4. Howler.js library
  5. Some sound

index.html

<!doctype html>
<html lang="en">
<head>
    <meta charset="utf-8">
    <title>Simple Metronome Demo</title>
    <meta name="description" content="Simple Metronome Demo">
    <meta name="author" content="Petr Nagy">
</head>
<body>
    <button onclick="start();this.setAttribute('disabled', 'true');">Start metronome !</button>
    <script src="howler.core.js"></script>
    <script src="app.js"></script>
</body>
</html>

app.js

var snd = new Howl({
    src: [ 'tick.wav' ],
    volume: 1.00,
});

function play() {
    snd.play();
} // end function

function start() {
    var worker=newWorker('Worker.js');
    worker.onmessage=function (e) {
        play();
    };
    worker.postMessage('1000');
} // end function

Worker.js

var interval = null;
onmessage = function(e) {
    interval=setInterval(function() {
        postMessage('');
    }, parseInt(e.data));
};

And voilá!

Tick – tock – tick – tock

The whole example can be downloaded here.


Note on compatibility: I have tested this in the latest Firefox, Chrome, Edge & Safari. Safari does not support the ticking while the tab is inactive, other browsers have no problem with it.

Note #2: Why Howler.js and not classic html5 audio? The answer is better cross browser compatibility.

Leave a Reply

Questions? Something to add? Let's discuss!

Simply @mention me on Twitter and start the discussion.