I have a redux app which uses requestAnimationFrame
to render a new state on every TICK, however Google Chrome seems to be calling requestAnimationFrame
up to 3 times(!!) for some ticks, and not at all for others, leading to janky animations.
In React development mode:
In React
NODE_ENV=production
mode:
It's rendering at 60fps already, so multiple unnecessary requestAnimationFrame
callbacks per 16ms frame are highly wasteful of CPU resources. Frames that don't have a tick also cause laggy-ness in the animations. My tick function only takes 4ms to compute (well under the 16ms budget), and I only have one callback running on the page.
Here is the animation code that handles dispatching my redux call on every tick.
class AnimationHandler {
constructor(store) {
this.store = store
this.animating = false
store.subscribe(::this.handleStateChange)
}
handleStateChange() {
if (!this.animating) {
this.tick()
}
}
tick(timestamp) {
this.animating = true
this.store.dispatch({
type: 'TICK',
current_timestamp: (new Date).getTime(),
// reducer handles updating rendered state to this point in time
})
window.requestAnimationFrame(::this.tick)
}
}
window.animations = new AnimationHandler(window.store) // redux store
What could be causing Chrome to do this, and how can I make it so that there's one consistent tick()
call per frame rendered, no more no less?