要避免的javascript构造?

要避免的javascript构造?,javascript,algorithm,optimization,Javascript,Algorithm,Optimization,我一直在写一个JS算法。它在铬合金中燃烧得很快,在FF中燃烧得很慢。在chrome profiler中,正如您所发现的,不同的实现中存在不同的问题。根据我的经验,除非做一些非常愚蠢的事情,否则在目标浏览器上测试时遇到特定的性能问题之前/除非您遇到特定的性能问题,否则担心优化JavaScript代码以提高速度并没有多大意义。像通常的“倒计时到零”优化(for(i=length-1;i>=0;--i)而不是for(i=0;i

我一直在写一个JS算法。它在铬合金中燃烧得很快,在FF中燃烧得很慢。在chrome profiler中,正如您所发现的,不同的实现中存在不同的问题。根据我的经验,除非做一些非常愚蠢的事情,否则在目标浏览器上测试时遇到特定的性能问题之前/除非您遇到特定的性能问题,否则担心优化JavaScript代码以提高速度并没有多大意义。像通常的“倒计时到零”优化(
for(i=length-1;i>=0;--i)
而不是
for(i=0;i
)这样的简单事情在实现中甚至都不可靠。因此,我倾向于坚持编写相当清晰的代码(因为我想善待那些需要维护它的人,通常是我),然后担心优化的可能性和时间

也就是说,通过查看与in相关的tszming提醒我,在最初编写代码时,我往往会记住一些性能方面的事情。下面是一个列表(有些来自那篇文章,有些不是):

  • 当您用大量片段构建一个长字符串时,如果您构建一个片段数组,然后使用
    array#join
    方法来创建最终字符串,通常会获得更好的性能。如果我正在构建一个要添加到页面中的大型HTML片段,我会经常这样做

  • 这款手机虽然很酷,功能强大,但价格昂贵。我倾向于回避它

  • 使用
    成本高昂,而且容易被误解。避免它

  • 当然,内存泄漏最终是昂贵的。当您与DOM元素交互时,在浏览器上创建它们相当容易。有关更多详细信息,请参阅本文,但基本上,使用jQuery、Prototype、Closure等良好的库连接事件处理程序(因为这是一个特别容易出现的领域,库会提供帮助),并避免通过expando属性(直接或间接)在其他DOM元素上存储DOM元素引用

  • 如果您正在浏览器中构建内容的重要动态显示,
    innerHTML
    在大多数情况下比使用DOM方法(
    createElement
    appendChild
    )要快得多。这是因为浏览器可以高效地将HTML解析到其内部结构中,并且可以非常快速地完成,使用优化的编译代码直接写入其内部数据结构。相反,如果您使用DOM方法构建一个重要的树,那么您使用的是一种解释(通常)语言与浏览器必须翻译以匹配其内部结构的抽象进行对话。我前一段时间做了,差别大约有一个数量级(有利于
    innerHTML
    )。当然,如果您正在构建一个大字符串以分配给
    innerHTML
    ,请参阅上面的提示-最好在数组中构建片段,然后使用
    join

  • 缓存已知的慢速操作的结果,但不要过度,只在需要时保存。请记住保留引用的成本与再次查找引用的成本

  • 我反复听到人们说从包含范围访问变量(当然,globals将是这方面的最终示例,但您可以使用其他范围中的闭包)比访问本地变量要慢,当然这在纯解释的情况下是有意义的,由于范围链的定义方式,未优化实现。但我从未真正看到实践证明这是一个显著的差异。()实际全局变量是特殊的,因为它们是
    窗口
    对象的属性,它是一个宿主对象,因此与用于其他范围级别的匿名对象略有不同。但我想你已经避开了环球

  • 这里有一个#6的例子。几周前,我在一个与原型相关的问题中看到了这一点:

    for (i = 0; i < $$('.foo').length; ++i) {
        if ($$('.foo')[i].hasClass("bar")) { // I forget what this actually was
            $$('.foo')[i].setStyle({/* ... */});
        }
    }
    
    …但进一步使用它(例如向后工作到零)是没有意义的,它可能在一个浏览器上更快,在另一个浏览器上更慢。

    给你:


    我不认为这是一个真正的性能问题,但除非你知道发生了什么,否则一定要避免:

    var a = something.getArrayOfWhatever();
    for (var element in a) {
      // aaaa! no!!  please don't do this!!!
    }
    
    换句话说,使用
    来。。。在
    中,应避免在数组上构造。即使在遍历对象属性时,也很棘手


    另外,我最喜欢避免的事情是避免在声明局部变量时省略
    var

    请不要只做链接回答:另一个原因是链接可能会在一段时间后断开…或者实际上是全局变量!与“倒计时到0”相关,我最近看到了另一个变体,我认为它很聪明(如果有点混乱):
    用于(var I=arr.length;I-)
    @Ryan::-)是的,我见过那个(以及它的表亲,
    var I=arr.length;而(I-)…
    ),变量很便宜。赋值也很便宜,因为它只复制基本值,或者对象的引用。我不认为这会成为性能瓶颈。@galambalazs当做一件事数十万次时,我想每个作业都很重要?当然可以看看这个。就快到了,只需要多一点支持:)
    for (i = 0; i < $$('.foo').length; ++i) {
        if ($$('.foo')[i].hasClass("bar")) { // I forget what this actually was
            $$('.foo')[i].setStyle({/* ... */});
        }
    }
    
    list = $$('.foo');
    for (i = 0; i < list.length; ++i) {
        if (list[i].hasClass("bar")) { // I forget what this actually was
            list[i].setStyle({/* ... */});
        }
    }
    
    var a = something.getArrayOfWhatever();
    for (var element in a) {
      // aaaa! no!!  please don't do this!!!
    }