小编Sta*_*ski的帖子

requestAnimationFrame在帧结束前调用了吗?

我一直在试验HTML5画布上复杂场景的无抖动渲染.我们的想法是将渲染分成多个批次,每个批次最多占用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
    } 
  }); 
}
Run Code Online (Sandbox Code Playgroud)

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

  • 在每个帧上,修改画布的CSS转换属性(这是同时运行的快速执行动画的示例).
  • 偶尔,以批量方式启动画布的重新渲染,如上所示.

不幸的是,在重新渲染画布内容的时候,我正好看到了可怕的janks.我似乎无法解释的是Chrome开发者工具时间轴的样子:

Chrome开发者工具时间轴视图中的Janks

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

渲染到离屏画布(https://jsfiddle.net/fkfnjrc2/6/),然后将完整的图像复制到屏幕画布有点帮助,但是janks仍然存在完全相同的特征(延迟执行rAF回调).

这段代码出了什么问题?或者我的浏览器/机器可能有问题?我在Windows 10和Mac OS上的Chrome(49.0.2623.112)上看到了相同的行为.

javascript performance animation canvas requestanimationframe

5
推荐指数
1
解决办法
550
查看次数