【问题标题】:Javascript: Optimizing details for Critical/Highly Processed Javascript codeJavascript:优化关键/高度处理的 Javascript 代码的细节
【发布时间】:2010-11-09 02:31:24
【问题描述】:

我已经浏览了很多 Javascript 优化,其中大多数都在谈论字符串连接,还有一些其他大的发现 here,但我认为必须有 更多详细信息您可以针对速度关键且这些代码段的处理非常高进行优化。

假设您出于某种原因运行此代码:(不太可能,我知道,但请耐心等待)

for( var i = 0; i < 100000000000; i++ ) {
  //Do stuff
}

而且没有办法绕过那么大的循环......您将要确保您在该循环中所做的所有事情都已优化到您无法优化的程度不再...否则您的网站将挂起。

编辑:我说的不一定是循环,像 onmousemove 这样反复调用的函数呢?虽然在大多数情况下我们不需要使用 onmousemove,但在某些情况下会这样做
这个问题是针对这些情况的。

使用 JQuery 作为我们的 JS 库

所以我想要的是优化技巧,但仅限于更不常见的技巧
- IE。 Speed differences between switch or if-else

如果您想查看更常见的,可以在这里找到它们:

【问题讨论】:

  • 我建议把这个问题改成wiki。

标签: javascript optimization


【解决方案1】:

“而且没有办法绕过那么大的循环......”

在 RIA 的现实世界中,您必须绕过大循环。与优化同样重要的是学习如何将大循环分解为小循环,并为浏览器留出时间来处理其 UI。否则你会给你的用户一个糟糕的体验,他们不会回来。

所以我认为在你学习时髦的 JS 优化之前,你应该知道如何将一个大循环分成由 setTimeout() 调用的块并显示一个进度条(或让动画 GIF 循环)。

感知速度通常比实际速度更重要。客户端的世界不同于服务器的世界。


制作动画时,了解如何确定您是否在蹩脚的浏览器(通常是 IE)上运行,并尝试降低帧速率(或者干脆不制作动画)。我可以让一些动画在一个好的浏览器中达到 90fps,但在 IE 中只有 15fps。您可以测试浏览器,但通常最好使用超时和时钟来查看动画的执行情况。


另外,为了真正的加速,了解如何在 Gears 和更新的浏览器中使用 web workers

【讨论】:

  • 这不一定是关于循环的。如果它是一个经常被调用的函数怎么办?例如,onmousemove 事件,即使函数很短,它仍然会减慢处理速度。
  • @Matt:在大多数情况下,您可能最终不需要在鼠标移动或窗口正在调整大小 (IE) 时执行某些操作。你只需要在它结束时做一些事情。在这种情况下,您可以推迟处理程序的执行,使其只运行一次。看到这个 - ajaxian.com/archives/delaying-javascript-execution
  • @Chetan Sastry:我以 onmousemove 事件为例,因为我的网站使用鼠标移动。想想类似于在移动时自动显示鼠标坐标的东西,只是要复杂得多。请不要基于“大多数情况”而忽略问题,如果每个人都这样做,那么那些不属于“大多数情况”类别的问题将永远无法解决。
  • @Matt:我没有驳回你的问题。我刚刚回答了一个具体案例,人们倾向于认为他们需要不断跟踪每一次鼠标移动,但实际上,起点和终点正是他们所需要的。如果您的案例不属于该类别,请忽略。其他人仍然可以看到您的问题并会回答,希望
  • 所以这不是循环,也不是 onmousemove。很难回答一个移动的目标。不同的情况需要不同的技术。
【解决方案2】:

你可以这样加速这个 mofo:

for (var i = 100000000; i--;) {
  //Do stuff
}

反转循环并仅检查

i-- 

而不是

i < 10000000 and i < 10000000 = true

在大多数浏览器中性能提升 50%

在一个很棒的 Google Code 演讲中看到了这一点 @http://www.youtube.com/watch?v=mHtdZgou0qU 该演讲还包含其他一些很棒的技巧。

祝你好运!

【讨论】:

  • 谢谢!现在有人真正知道如何提供帮助。尽管 Nosredna 在避免大循环方面有一个好处,但就我而言,我别无选择,必须捕获 onmousemove 事件并且每次都必须进行函数调用,所以我感谢那些不回来告诉我的人他们比我知道我的程序需要如何更好地工作。我只想回答我的问题,而不是批评。
【解决方案3】:

如果不需要同步,则使用 setTimeout 调用将循环转换为递归实现

for( var i = 0; i < 100000000000; i++ ) {
    //Do stuff
}

大概可以写成

function doSomething(n)
{
    if (n === 0) return some_value;
    setTimeout(function(){doSomething(n-1);}, 0);
}

好的,这可能不是一个很好的例子,但你明白了。这样,您可以将长同步操作转换为不会挂起浏览器的异步操作。在某些不需要立即完成某事的情况下非常有用。

【讨论】:

【解决方案4】:

使用split & join 代替replace

//str.replace("needle", "hay");
str.split("needle").join("hay");

【讨论】:

    【解决方案5】:

    将长引用链存储在局部变量中:

    function doit() {
        //foo.bar.moo.goo();
        //alert(foo.bar.moo.x);
    
        var moo = foo.bar.moo;
    
        moo.goo();
        alert(moo.x);
    }
    

    【讨论】:

    • 即使没有引用链,在循环中将局部变量分配给当前作用域之外的变量仍然是有益的,因为 JavaScript 首先在当前作用域中查找变量,然后在父作用域中查找,依此类推.
    【解决方案6】:

    看到这里的人给出了一些不错的答案后,我又做了一些搜索,找到了一些补充:

    这些是关于 Javascript 优化的技巧,当您希望深入了解非常小的细节时,在大多数情况下这些事情并不重要,但有些事情会有所作为:

    Switch vs. Else If

    一种常用的绞杀策略 任何开销都可能被排除在外 一大群简单的条件 语句正在替换 If-Then-Else 的 使用 Switch 语句。

    如果您想查看基准测试,您可以找到它here

    循环展开

    要展开循环,您需要做更多事情 比每一个相同的步骤 迭代并递增计数器 相应地变化。这很有帮助 因为你然后减少了数字 您检查的次数 整个循环的条件。你 这样做时必须小心 因为你最终可能会超调 界限。

    查看详细信息和基准测试here

    反向循环计数

    反转你的循环,让它计数 向下而不是向上。我也看过 在有关的各种文件中 比较数字的优化 归零比比较快得多 它到另一个号码,所以如果你 递减并与零比较 应该更快。

    查看更多详细信息和基准测试here

    达夫的装置
    这很简单,但一开始很难掌握。阅读更多关于它的信息here
    请务必查看该页面下方的改进版本。

    此信息的大部分直接引用自此处:JavaScript Optimization。这很有趣,因为它是一个如此古老的网站,它从他们当时拥有的浏览器处理能力的角度来看待优化。虽然他们记录的基准测试是针对 IE 5.5 和 Netscape 4.73,但他们的基准测试工具可以为您使用的浏览器提供准确的结果。

    对于那些认为这些细节无关紧要的人来说,我认为这说明了人们对我们所拥有的先进技术力量的看法。仅仅因为我们的浏览器的处理速度比过去快很多倍,并不一定意味着我们应该滥用这种处理能力。

    我并不是建议花几个小时在 0.005 毫秒内优化两行代码,但是如果您牢记这些技术并在适当的地方实施它们,它将有助于更快的网络。毕竟,there are still many people using IE 6,所以假设每个人的浏览器都可以处理相同的处理是错误的。

    【讨论】:

    • 刚刚在 Chrome 中尝试了这些测试...有些显然仍然值得!
    【解决方案7】:

    我们应该针对哪个 JavaScript 引擎?如果您谈论的是这种极端的优化,那将有很大的不同。首先,我将指出用于字符串连接的 array.join() 技巧仅适用于 Microsoft 的 JScript 引擎。它实际上可以在其他 JS 引擎上提供更差的性能。

    【讨论】:

    • 有一个很好的论据可以证明它实际上只有 IE 需要优化。如果你让它在 IE 上运行得很快,它在其他浏览器中会非常快。
    猜你喜欢
    • 2017-02-18
    • 1970-01-01
    • 2015-11-08
    • 1970-01-01
    • 1970-01-01
    • 2020-06-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多