2

我有一些关于 JavaScript 循环的问题。

问题 :

  • 为什么 JavaScript 循环会冻结浏览器
  • 为什么绘图速度很慢,即使它每 1 毫秒运行 1 次,而且它正在绘制最简单的东西!
  • 解决方案是什么?flash快要死了,我们现在该怎么办?

这是您自己尝试的画布代码:

<!doctype html>
<html>
<head>
</head>
<body>
    <canvas id="c" width="400" height="400"></canvas>
    <script type="text/javascript">

        var c = document.getElementById( 'c' );

        ctx = c.getContext( '2d' );

        var x = 100;

        ctx.fillStyle= '#f00';

        function loop()
        {
            ctx.fillRect( x, 100, 20, 20 );

            ++x;
        }

        setInterval( loop, 1 );
    </script>
</body>
</html>
4

3 回答 3

10

为什么 JavaScript 循环会冻结浏览器(在 C++ 中不会发生)

JavaScript 是单线程的。DOM 的状态不能在 javascript 代码运行或竞争条件发生时改变。这意味着没有绘图/回流。

为什么绘图速度很慢,即使它每 1 毫秒运行 1 次,而且它正在绘制最简单的东西!

它不是以 1 毫秒运行,而是以 10 毫秒运行,因为浏览器不允许您如此紧密地循环。

解决方案是什么?flash快要死了,我们现在该怎么办?

使用 requestAnimationFrame 并以 60 FPS 运行游戏,为什么还需要更多?

使用(webkit)requestAnimationFrame的示例,它对我来说运行顺利。

于 2011-11-13T00:19:00.603 回答
2

一毫秒是一个极短的时间间隔。
这是一个如此短的时间间隔,以至于您的代码将几乎连续地在 UI 线程中运行,从而使浏览器无响应。

您需要暂停以给用户时间与页面进行交互。

使用至少十毫秒的间隔,最好是一百毫秒。

于 2011-11-13T00:18:26.650 回答
0

帧率下降并最终导致浏览器冻结的原因是由于画布元素占用的内存。我已经回答了这个问题。你可以在这里找到线程。

每次您在画布上绘制某些内容时,该操作都会保存到画布的路径中。每次在画布上绘制内容时,此路径会占用更多内存。如果您不清空画布的路径,则会出现帧率下降。例如,查看您的 javascript 与清除画布路径的 javascript 之间的执行时间差异,

var c = document.getElementById( 'c' );
ctx = c.getContext( '2d' );
var x = 100;
ctx.fillStyle= '#f00';

function loop()
{
    ctx.beginPath(); 
    ctx.fillRect( x, 100, 20, 20 );

    ++x;
}
setInterval( loop, 1 );
于 2014-05-25T18:53:39.350 回答