requestAnimationFrame在框架结束之前调用? [英] requestAnimationFrame called right before the end of the frame?

查看:634
本文介绍了requestAnimationFrame在框架结束之前调用?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经在HTML5画布上尝试无复制渲染复杂场景。想法是将渲染分割成多个批次,每个批次最多花费例如12ms,使得同时运行的动画(执行起来非常便宜)不被中断。



概念上来说,批量渲染是这样实现的:

  draw(ctx){
var deadline = window.performance.now()+ 12; //不准确,但对于示例而言足够
var i = 0;
requestAnimationFrame(function drawWithDeadline(){
for(; i< itemsToRender.length; i ++){
if(window.performance.now()> = deadline){
requestAnimationFrame(drawWithDeadline);
return;
}

var item = itemsToDraw [i];
//绘制项目
}
});
}

完整的代码在这个JSFiddle中:)然后将完整的图像复制到屏幕画布有助于一点,但是janks仍然在那里具有完全相同的特性(延迟执行rAF回调)。



该代码有什么问题?或者我的浏览器/机器有问题?我在Windows 10和Mac OS上看到的Chrome(49.0.2623.112)有相同的行为。

解决方案

是由Chrome的具体requestAnimationFrame回调调度引起的。我提交了错误来跟踪此问题,其中包含一些更简单的再现代码示例。


I've been experimenting with jank-free rendering of complex scenes on HTML5 canvas. The idea is to split rendering into multiple batches with each batch taking a maximum of, say 12 ms, so that the concurrently running animations (very cheap to execute) are not interrupted.

Conceptually, batch-rendering is implemented like this:

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
    } 
  }); 
}

The complete code is in this JSFiddle: https://jsfiddle.net/fkfnjrc2/5/. The code does the following things:

  • On each frame, modify the CSS transform property of the canvas (which is an example of the concurrently-running fast-to-execute animation).
  • Once in a while, initiate re-rendering of the canvas in the batched fashion as shown above.

Unfortunately, I'm seeing horrible janks exactly at the times when canvas contents is re-rendered. What I don't seem to be able to explain is what the Chrome Developer Tools timeline looks like:

The dropped frames seem to be caused by the fact that the requestAnimationFrame is not called right at the start of the frame, but towards the end of the ideal 16ms period. If the callback started right after the previous frame completed rendering, the code would most likely complete in time.

Rendering to an off-screen canvas (https://jsfiddle.net/fkfnjrc2/6/) and then copying the complete image to the screen canvas helps a little, but the janks are still there with exactly the same characteristics (delayed execution of rAF callback).

What is wrong with that code? Or maybe something's wrong with my browser / machine? I'm seeing the same behaviour on Chrome (49.0.2623.112) on Windows 10 and Mac OS.

解决方案

The issues seem to be caused by Chrome's specific requestAnimationFrame callback scheduling. I've filed a bug to track this, it contains some simpler reproduction code examples.

这篇关于requestAnimationFrame在框架结束之前调用?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆