Why is the requestAnimation frame called multiple times for some frames and not others?

I have a redux app that uses requestAnimationFrame

to render a new state on every TICK, however Google Chrome seems to call requestAnimationFrame

up to 3 times (!!) for some ticks and not at all for others, resulting in a janky animation.

In React Chrome performance timeline 1 mode : In React mode NODE_ENV=production

: Chrome 2 performance screenshot

This is rendering at 60 frames per second, so numerous unnecessary callbacks requestAnimationFrame

per 16ms frame is very wasteful of CPU resources. Borders that don't have a checkmark also cause animation lag. My tick function only takes 4ms to compute (well under the budget of 16ms) and I only have one callback per page.

Here is the animation code that handles 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 can get Chrome to do this, and how can I make it so that one sequential tick()

call for each processed frame, no more, no less?

+3


source to share





All Articles