我有一个循环,每30毫秒通过一个window.setInterval调用。
它看起来像这样:
var loop = function (w, t){
for( i=0; i<w; i++){
value= something*t;
ctx.strokeStyle="rgba(" + Math.floor(color[0]*value) + "," + Math.floor(color[1]*value) + "," + Math.floor(color[2]*value) + "," + 255 + ")";
ctx.lineWidth = 1;
ctx.beginPath();
ctx.moveTo(i ,0);
ctx.lineTo(i ,h);
ctx.closePath();
ctx.stroke();
}
}
var color =[0,0,0];
var myLoop=window.setInterval(function(){
loop(width, time);
}, 30);
供参考,w通常为~1000-1500
当我在电脑上运行时,我完全没有问题。但是,在内存较少的设备上运行程序运行速度非常慢(即它慢慢地绘制到画布上)。
我想我某处有一些内存泄漏,但我看不到哪里。
或者,我可能会疯狂,分配1000个画布路径太多了。但我找不到画布绘制方法如何分配内存的解释。
任何提示?
答案 0 :(得分:2)
在这里给出的例子中有几个问题:
i, h, time, something
未定义。未使用var
定义的所有变量都会使window
对象变脏。始终明确声明所有变量。
当alpha通道= 255时,您无需使用rgba
,只需使用rgb
。
您可以使用fillStyle
代替,这样您就可以使用fillRect了 - 这与moveTo + lineTo的作用相同但是这个更加语义化:
ctx.fillRect(i, 0, i + 1 , h);
并且没有必要在这里使用closePath()
,因为你只是画一条线(没有任何东西可以关闭它 - 它只会在从最后一点回到开始时创建另一条线,所以你是除非这是由浏览器在内部进行优化,否则基本上会调整双倍。
使用requestAnimationFrame
(rAF)代替setInterval
。对于后者,你冒着堆叠呼叫的风险,它不会像rAF那样同步监视vblank(并且rAF效率更高)。在最坏的情况下,使用setTimeout
代替。
您也可以使用value|0
代替Math.floor
。
更新 - 我忘了还提到垃圾收集在繁忙的循环中会遇到困难。因此,对于移动设备而言,优化变得更加重要,因为那些CPU的功能不如台式计算机那么强大 - 优化的代码留下一些时间来说话。