注意到在Canvas中使用动画时我没想到的东西。我有一个相当简单的动画,五个不同大小的图像在一个循环中从屏幕的底部到顶部移动。
我将所有图像数据放在一个数组中,然后通过循环将它们绘制到画布上,然后使用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。知道为什么?还有其他方法来优化这个吗?
答案 0 :(得分:2)
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);
}
1)当requestAnimationFrame触发时,在更新前绘制,这样你就可以与屏幕同步了
2)将坐标四舍五入到最接近的64位,即在每个x坐标上使用&amp;(~3)可以加快速度。
3)你可以将一些clearRect组合在一起(=所有子弹/平铺的水平地板......)
4)我认为这里的主要问题是这些方法的开销
我做了一个jsperf知道更多:
http://jsperf.com/overhead-of-fillrect-and-clearrect/2
!!在测试过程中一定要看到帆布!!
结果:
Firefox ,clearRect的开销非常小,时间似乎也是如此 与像素数几乎成比例。 fillRect比较慢60%,看起来也很相称 面积覆盖。
64位Unalignment似乎没有在clearRect上有效,它使得表现 在fillRect上严重崩溃。
有些时候来自jsPerf(精度是如此):
全屏clearRect的208ns
55ns用于半屏clearRect - &gt; 4次使220ns vs 208
季度屏幕清晰度为13ns - &gt; 16次使208(!!!)
588ns全屏fillRect
1290ns半屏fillRect - &gt; 4次使1160
41ns四分屏幕填充 - &gt; 16次使656.
Safari ,所有结果都完全相同,除非有 更多开销:绘制4倍的点数只需要快3倍。
我知道精度是如此,但似乎在Firefox上
和Safari,结论是:
您清除屏幕的部分越少,删除的速度就越快。
Chrome :(日期05/14)fillRect比clearRect快得多。
IE11 :fillRect和clearRect名列前茅。
((如果有人可以在其他浏览器上看到,我会编辑 - 当我有时间 - ))
(假设你的图像是4像素对齐,代码是 64 align is:
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);
}
)
答案 1 :(得分:0)
由于人们在评论中回答,我觉得他们覆盖了我的问题。这是一个夏日:
每个clearRect()
占用的时间大致相同,因此最好少于几个。
要优化,应计算需要清除的区域,如果不是100%,则清除该区域。