注意到在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)我宁愿写:
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坐标上使用&(〜3)可以加快处理速度。
3)您可以将一些clearRect分组在一起(=所有子弹/平铺的水平地板,...)
4)我认为这里的主要问题是这些方法的开销。
我做了一个jsperf来了解更多信息:
http://jsperf.com/overhead-of-fillrect-and-clearrect/2
!!在测试过程中,请确保将画布放在视野中!!
结果:
Firefox,clearRect的开销非常小,而且时间似乎
与像素数几乎成比例。
fillRect慢了60%,而且看起来也很比例
面积覆盖。
64位不对齐对clearRect似乎没有影响,它可以提高性能
严重落在fillRect上。
有时来自jsPerf(精度一般):
208ns用于全屏clearRect
半屏清除效果为55ns-> 4倍使220ns与208
13ns的四分之一屏幕clearRect-> 16倍使208(!!!)
588ns全屏fillRect
1290ns半屏fillRect-> 4倍使1160
41ns四分之一屏幕fillrect-> 16倍使656。
Safari,除了有
更多的开销:减少4倍的点数仅快3倍。
我知道精度是马马虎虎,但似乎在Firefox
和Safari,结论是:
清除屏幕的内容越少,擦除的速度就越快。
并且更喜欢clearRect来fillRect-
Chrome :(日期05/14)fillRect比clearRect快得多。
IE11:fillRect和clearRect处于同等水平。
(((如果有人可以在其他浏览器上看到,我将在有时间的时候进行编辑-))
(只要您的图片对齐了4个像素,
64 align是:
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);
}
)