3

我有一个循环,每 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 个画布路径太多了。但是我找不到关于画布绘图方法如何分配内存的解释。

有什么提示吗?

4

1 回答 1

2

在您在这里给出的示例中,有几个问题:

i, h, time, something

没有定义。所有未定义的变量都会var使window对象变脏。始终显式声明所有变量。

rgba当 alpha 通道 = 255 时不需要使用,只需使用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 不如台式计算机上的功能强大——优化的代码留出了一些时间来喘口气。

于 2013-07-16T21:18:58.810 回答