为什么requestAnimation帧会为某些帧多次调用,而对其他帧则根本不调用?

时间:2017-06-28 03:26:56

标签: javascript reactjs animation redux requestanimationframe

我有一个redux应用程序,它使用requestAnimationFrame在每个TICK上呈现一个新状态,但Google Chrome似乎在调用requestAnimationFrame最多3次(!!)以获得某些刻度,而不是对所有人而言,导致janky动画。

在React开发模式中: Chrome performance timeline screenshot 1 在React NODE_ENV=production模式下: Chrome performance timeline screenshot 2

它已经以60fps呈现,因此每16ms帧多次不必要的requestAnimationFrame回调非常浪费CPU资源。没有勾号的帧也会导致动画中出现滞后现象。我的tick函数只需要4ms来计算(远低于16ms预算),而且我只在页面上运行一个回调。

这是动态代码,用于处理每个tick上调度我的redux调用。

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

可能导致Chrome执行此操作的原因是什么?我如何才能实现这一目标,以便每帧渲染一次tick()次调用,不多也不少?

1 个答案:

答案 0 :(得分:0)

我遇到了同样的问题。这是我的一个错误,我怀疑它总是如此。

在您的代码中,调用 num = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15] def check(num,each=4): for i in range(0,num,each): print(num[i:i+4]) check(16,4) 会安排 requestAnimationFrame 的无限循环,因为 requestAnimationFrame() 总是作为 tick() 的一部分被调用。这是正常的。

如果 import matplotlib.pyplot as plt from importlib import reload plt=reload(plt) 在循环外只被调用一次,这不是问题。这在您的示例中没有发生,但您可能在实际应用程序中启动了多个循环。

以防万一,我会将您的代码更改为:

tick()

就我而言,我重用了 tick() 方法,添加了 requestAnimationFrame() 层。

示例:(错误!)

handleStateChange() {
        if (!this.animating) {
            this.animating = true // immediate
            this.tick()
        }
    }