#development

requestAnimationFrame, setTimeout and setInterval in the background

I came across a peculiar bug recently. I was working on a web project where the student‘s client would mirror the timer clock of the teacher‘s client using a websocket connection. However, some students would receive more time than there actually is on the teacher‘s clock. It turns out that, when the teacher‘s client i.e. browser (tab) enters the background, requestAnimationFrame that is powering the timer does not fire in Google Chrome in a background tab. Websocket requests are sent like normal however.

So I whipped up a quick test script to see how requestAnimationFrame, setTimeout and setInterval behave in a background tab.

startTime = performance.now()
animationFrame = requestAnimationFrame(handleRequestAnimationFrame)
interval = setInterval(handleInterval, 100)
timeout = setTimeout(handleTimeout, 100)

function handleRequestAnimationFrame() {
   const x = (performance.now() - startTime) / 100
   // draw a line in the graph at point x
}
// etc.

The results for different browsers look as follows.

Diagram

Apparently, setTimeout and setInterval are the far better options if you want (limited) updates to continue in the background for some time. requestAnimationFrame is virtually halted while the tab is in the background (except for decreasing updates in Firefox).

Go ahead. Try for yourself!

requestAnimationFrame

setInterval

setTimeout