Clone wiki

timesheets / timing

Timing-control in the internal timer

Our timesheets engine uses the HTML5 Timing-control API in its internal timer. This API provides dynamic frame-update rates controlled by the User-Agent. It removes the need to use a setInterval or setTimeout to continuously call a function. And, along with it, optimises the animation both in visual and resource performance. It's the User-Agent who schedules the next frame update, and the JS code asks (via requestAnimationFrame() ) it to call a callback at that time.

The User-Agent is in a better position to determine the ideal frame update rate based on whether the page is currently visible or in a background tab, what the current load on the CPU is, and so on. Using this API should therefore result in more appropriate utilization of the CPU by the browser, and avoids the known performance problems of setInterval/setTimeout.

Benefits of using this API

  • The browser can optimize concurrent animations together into a single reflow and repaint cycle, leading to higher fidelity animation, eg. JS-based animations synchronized with CSS transitions.
  • A page in a tab that's not visible, the browser won't keep it running, which means less CPU, GPU, and memory usage, leading to graceful degradation in older machines and to a longer battery life.

Fallback implemented

If the browser doesn't support natively the Timing-control API, the engine will load a JS-based fallback that emulates its API. My code differs from the fallback code generally available (eg. link): their code uses a timer in each call to requestAnimationFrame(), while my approach uses a single timer for all client code requesting a frame. This can be specially important for the Timesheets engine, because there can be a LOT of time containers running at same time, therefore it's more efficient to have a single timer rather than one timer per container. [Note, the code is hosted in 'baselibs' repository.]

- (W3C Timing-control draft)