Javascript 清理整个画布比只清理部分更快?

Javascript 清理整个画布比只清理部分更快?,javascript,animation,canvas,html5-canvas,Javascript,Animation,Canvas,Html5 Canvas,在画布上玩动画时,我注意到了一些意想不到的事情。我有一个相当简单的动画,五个不同大小的图像在循环中从屏幕底部移动到顶部 我将所有图像数据放在一个数组中,并通过循环将它们绘制到画布上,然后使用window.requestAnimationFrame在下一帧上进行新的绘制 这里是有趣的部分,首先我刚刚清除了使用context.clearRect(0,0,canvas.width,canvas.height)渲染的每个帧的画布。然后我想这一定是在浪费计算,为每次渲染清除整个画布,即使屏幕上只有部分实际

在画布上玩动画时,我注意到了一些意想不到的事情。我有一个相当简单的动画,五个不同大小的图像在循环中从屏幕底部移动到顶部

我将所有图像数据放在一个数组中,并通过循环将它们绘制到画布上,然后使用
window.requestAnimationFrame
在下一帧上进行新的绘制

这里是有趣的部分,首先我刚刚清除了使用
context.clearRect(0,0,canvas.width,canvas.height)渲染的每个帧的画布。然后我想这一定是在浪费计算,为每次渲染清除整个画布,即使屏幕上只有部分实际更改

因此,我重写了清除画布的部分,以仅清除旧图像绘制的痕迹,使用如下方式:

for (var key in _images) {
   context.clearRect(_images[key].x-1, _images[key].y+_images[key].height, _images[key].width+2, 5);
}

但我也很惊讶这似乎慢了。。。首先我的帧速率是49-60,然后是47-57。你知道为什么吗?还有没有其他方法可以优化这一点?

因为人们在评论中回答了我的问题,我确实觉得他们涵盖了我的问题。这是一个夏天:

每个
clearRect()
占用的时间大致相同,因此最好是少而不是多

要优化,应计算需要清除的区域(如果不是100%),并清除该区域。

0)我宁愿写:

for (var i=0, len=_images.length; i<len; i++) {
   var thisImage = _images[i];
   context.clearRect(thisImage.x, thisImage.y, thisImage.width, thisImage.height);
}
for(var i=0,len=_images.length;i 4倍等于220纳秒vs 208
四分之一屏幕clearRect为13ns->16次为208(!!!)

588ns全屏fillRect
1290ns半屏幕fillRect-->4次生成1160
41ns四分之一屏幕fillrect-->16次等于656

Safari,所有结果都是一样的,只是有 更高的开销:只需3倍的速度就可以减少4倍的分数

我知道精度很低,但在firefox上 对于Safari,结论是:
屏幕上清除的部分越少,擦除的速度越快

  • 更喜欢clearRect而不是fillRect-
Chrome:(日期:2014年5月)fillRect比clearRect快得多

<强> IE11 :FILRCITE和CISRCORT均为标准值。

((如果有人可以在其他浏览器上看到,我会编辑-当我有时间-)

(如果您的图像是4像素对齐的,则代码 64.这是:

for (var i=0, len=_images.length; i<len; i++) {
   var thisImage = _images[i];
   var x = thisImage.x ;
   context.clearRect(x & (~3), thisImage.y, thisImage.width + ((x&3)&&(16-(x&3))), thisImage.height);
}

用于(var i=0,len=_images.length;i因为循环,和/或因为清除整个画布在内部得到了更好的优化,也许?每个ClearRect占用的时间大致相同,因此,现在不是一个ClearRect调用,而是三个ClearRect调用。由于使用的数学和引用,三个ClearRect调用也有一点开销。您应该计算需要清除的rect,然后只调用一次clearRect。即图像的并集。清除整个画布总是比清除其中的许多部分更好?但也最好尽可能少地清除,因此,如果您的更改仅在画布的50%中,最好只清除50%。清除整个画布可能“更好”在画布上,GPU为您解决了大部分问题。收益将是微乎其微的。我运行了您的测试。在最新的Chrome中,fillRect比clearRect快很多(8000比1000000)。在IE11中,差不多(7MM)@subkamran:谢谢你的更新。我认为只要blink还在开发中,我们就会有奇怪的bug或性能数据。不过我不确定我会花时间查看所有当前浏览器……我更新了你的评论,事实上,如果你想的话,可以随意编辑帖子。