如何提升JavaScript循环的运行速度
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何提升JavaScript循环的运行速度相关的知识,希望对你有一定的参考价值。
提升javascript循环的运行速度的方法很简单的,减少每次循环的时间复杂度. 或者提高CPU的性能.就可以了。 参考技术A 循环中的过多操作。循环的操作是同步进行的,所以执行一个循环所花费的时间完全取决于循环的次数。因此有两种情况 会导致循环执行的时间过长,并直接导致锁定浏览器。一是循环体中包含了太多的操作,二是循环的次数过多。这两种情况都能直接导致锁定浏览器,并显示脚本失 控的提示。解决这个问题的诀窍就是用下面这两个问题来评估每个循环:
1. 这个循环必须要同步执行么?
2. 循环里面的数据,必须要按顺序执行么?
如果两个问题的答案都是否定的话,你就可以选择将循环里的操作进行分解。关键是要根据代码的具体环境确定上面两个问题的答案。一个典型的循环可能像下面这个样子:
for(var i=0; i < items.length; i++)
process(items[i]);
乍 一看这个循环并没有太大的问题,是不是会运行很长时间完全取决于循环的次数。如果紧接循环后没有其他代码在执行的时候需要依赖于循环的结果,那么对于第一 个问题的答案就是“不”。你还可以发现,循环每次只处理一个数值,而且不依赖于上一次循环的结果,所以对于第二个问题的答案同样也是否定的。这就意味着, 循环可以通过某种方式进行拆解,不会导致锁定浏览器而显示脚本失控的提示。 参考技术B 优化循环内的算法,或者换处理器
Javascript 游戏循环
【中文标题】Javascript 游戏循环【英文标题】:Javascript Game Loop 【发布时间】:2011-11-13 00:15:53 【问题描述】:我有一些关于 JavaScript 循环的问题。
问题:
为什么 JavaScript 循环会冻结浏览器 为什么绘制速度很慢,即使它以每 1 毫秒绘制 1 次的速度运行,而且绘制的是最简单的东西! 有什么解决办法? flash 快要死了,我们现在该怎么办?这是你自己尝试的画布代码:
<!doctype html>
<html>
<head>
</head>
<body>
<canvas id="c" ></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>
【问题讨论】:
你的电脑有多牛?听起来不太强大 @AustinHenley 不过它会被 HTML5 取代,因为它是一个更合适的工具 与本帖相同***.com/questions/25612452/… 不要使用setInterval()
替换为window.requestAnimationFrame()
【参考方案1】:
为什么 JavaScript 循环会冻结浏览器(在 C++ 中不会发生)
JavaScript 是单线程的。 DOM 的状态不能在 javascript 代码运行或竞争条件发生时改变。这意味着没有绘图/回流。
为什么绘图速度很慢,即使它以每 1ms 1 次绘图运行,而且它正在绘制最简单的东西!
它不是以 1 毫秒运行,而是以 10 毫秒运行,因为浏览器不允许您如此紧密地循环。
解决办法是什么? flash快死了,我们现在该怎么办?
使用 requestAnimationFrame 并以 60 FPS 运行游戏,为什么还需要更多?
Example using (webkit) requestAnimationFrame 对我来说运行流畅。
【讨论】:
(webkit/mozilla)RequestAnimationFrame 并不真正与刷新率同步,它只是一个基于刷新率的时间间隔回调。通过这种推算,以两倍的帧速率进行渲染可以看到渲染平滑度的提高,而如果它是完美的定时则不会。问题在于,您在浏览器中找到的 JavaScript 从未被设计为执行我们真正希望在浏览器中执行的高性能多线程任务。这不是 JavaScript 的缺点,只是将 JavaScript 用作浏览器中的单线程事件接收器。 "JavaScript 是单线程的。"不是真的 javascript 是多线程的developer.mozilla.org/en-US/docs/Web/Guide/Performance/…【参考方案2】:一毫秒是一个极短的时间间隔。 时间间隔如此之短,以至于您的代码几乎会一直在 UI 线程中运行,从而导致浏览器无响应。
您需要留出停顿,让用户有时间与页面互动。
使用至少十毫秒的间隔,最好是一百毫秒。
【讨论】:
根本不是这样。 setInterval 不会使浏览器无响应。 @Raynos:当区间中的代码运行时,浏览器没有响应。如果代码没有运行没有任何时间,浏览器将不会响应。 但是浏览器有一个最小设置超时来避免这个确切的问题。这个最小值是 10。这也不是问题。浏览器可以在 10 毫秒内完成大量回流渲染 @Raynos:这是限制标准吗?这是在哪里指定的?我没有意识到这一点。 对于 Firefox 来说似乎是 4 毫秒:mxr.mozilla.org/mozilla-aurora/source/dom/base/…【参考方案3】:帧率下降并最终导致浏览器冻结的原因是由于画布元素占用的内存。我已经回答了这个问题。你可以找到线程here。
每次你在画布上绘制东西时,该操作都会保存到画布的路径中。每次在画布上绘制内容时,此路径会占用更多内存。如果您不清空画布的路径,则会出现帧率下降。例如,查看您的 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 );
【讨论】:
以上是关于如何提升JavaScript循环的运行速度的主要内容,如果未能解决你的问题,请参考以下文章