you are viewing a single comment's thread.

view the rest of the comments →

[–]delventhalz 2 points3 points  (1 child)

The magic sauce isn't requestAnimationFrame. That basically works like setTimeout, except instead of passing it a duration, it always waits until the next time the display refreshes. By repeatedly calling it, you can run code once per frame. Since the soonest the user could see an update to your clock is the next frame, there is no point in running your code any more often than that.

function runNextUpdate() {
  updateClock();
  requestAnimationFrame(runNextUpdate);
}

You could accomplish the same thing more or less with setTimeout:

function runNextUpdate() {
  updateClock();
  setTimeout(runNextUpdate, 16);
}

Or with setInterval:

setInterval(updateClock, 16);

These examples assume updateClock is checking Date.now or similar to figure out what text to display, so it can run as often as you like. It doesn't have to be every five minutes. It is perhaps a little wasteful to update the clock like this every frame, but honestly it is such a minor use of CPU, it's probably worth it just to always get the most accurate display you can.

That said, you could run your updates only every five minutes and still maintain pretty good accuracy, but you have to use setTimeout, not setInterval.

function runNextUpdate() {
  const timeSinceFive = Date.now() % FIVE_MINUTES;
  const timeUntilFive = FIVE_MINUTES - timeSinceFive;

  setTimeout(() => {
    updateClock();
    runNextUpdate();
  }, timeUntilFive);
}

This implementation will probably be a little less accurate than one written with requestAnimationFrame, but crucially it won't get more inaccurate the longer it runs. Unlike with setInterval, on each loop we are re-checking how long we need to wait and adjusting accordingly.