requestAnimationFrame 在帧结束之前调用?

requestAnimationFrame called right before the end of the frame?

我一直在 HTML5 canvas 上试验复杂场景的无卡顿渲染。这个想法是将渲染分成多个批次,每个批次最多花费 12 毫秒,这样并发的 运行 动画(执行起来非常便宜)不会被打断。

从概念上讲,批量渲染是这样实现的:

function draw(ctx) {
  var deadline = window.performance.now() + 12; // inaccurate, but enough for the example
  var i = 0;
  requestAnimationFrame(function drawWithDeadline() {
    for (; i < itemsToRender.length; i++) {
      if (window.performance.now() >= deadline) {
        requestAnimationFrame(drawWithDeadline);
        return; 
      }

      var item = itemsToDraw[i];
      // Draw item
    } 
  }); 
}

完整代码在这个 JSFiddle 中:https://jsfiddle.net/fkfnjrc2/5/。该代码执行以下操作:

不幸的是,我在重新呈现 canvas 内容时恰好看到可怕的卡顿。我似乎无法解释的是 Chrome 开发人员工具时间轴的样子:

丢帧似乎是由于 requestAnimationFrame 没有在帧开始时调用,而是在理想的 16 毫秒周期结束时调用。如果回调在前一帧完成渲染后立即开始,代码很可能会及时完成。

渲染到屏幕外 canvas (https://jsfiddle.net/fkfnjrc2/6/) 然后将完整图像复制到屏幕 canvas 有点帮助,但卡顿仍然存在相同的特性(延迟执行 rAF 回调)。

该代码有什么问题?或者我的浏览器/机器有问题?我在 Chrome (49.0.2623.112) 在 Windows 10 和 Mac OS.

上看到相同的行为

这些问题似乎是由 Chrome 的特定 requestAnimationFrame 回调调度引起的。我已经提交了一个 bug 来跟踪这个,它包含一些更简单的复制代码示例。