jQuery:add()性能;有没有更好的办法?

时间:2012-04-05 19:35:01

标签: javascript jquery arrays performance add

我想做什么:将页面上的所有相似元素(某种类型)分组到一个我可以稍后迭代的对象中 - 或者对其中的每个元素应用彻底的更改。

我的代码成功完成了给定的任务,但是当元素数量增长到200-300 +时,性能急剧下降,用户已经注意到了。我已经隔离了有问题的代码行,想知道是否有其他方法可以解决同样的问题。

add()函数似乎是基于我放置它们的计时器的有问题的操作。首先,执行操作所需的时间是.001但是会增长,直到元素数达到300,并且每增加一个元素需要〜0.1秒并继续减速。

我有researchedand more)jQuery性能增强功能,并实现了其中一些(即3),但他们没有给我任何有意义的性能提升。令人惊讶的是,此代码在1秒内(!)执行Firefox(300多次调用add()),而Chrome和IE大约需要10-20倍或更长时间......

这是我的代码:

rowsToChange = $([]);
// Grab all the ids greater than whichever one I'm currently looking at:
var arr = $.makeArray($("[id^=stackLocatorLinkFillUp]:gt("+(uniqueID-1)+")"));
for (var i=0; i<arr.length; i++) {
    $this = arr[i];
    // <<< VARIOUS CONDITIONALS that make this as selective as possible REMOVED >>>
    startTimer = new Date().getTime();
    // **************************
    // PROBLEMATIC LINE FOLLOWS when 200+ records:
    rowsToChange = rowsToChange.add($this);
    // Grows from .001 to .1xx after 300 iterations
    console.log("innertiming:"+(new Date().getTime() - startTimer)/1000);
    // **************************
}

最终结果如下(通过Chrome Inspector):

[<div style=​"display:​none" id=​"stackLocatorLinkFillUp1">​itemType=BOUND&ccLocale=PERIODICAL​</div>​, 
<div style=​"display:​none" id=​"stackLocatorLinkFillUp2">​itemType=BOUND&amp;ccLocale=PERIODICAL​</div>​,
...
]

最终我按照以下方式处理所有这些(我非常喜欢简单!):

var superlink = "...new <a> goodness to display for all elements...";
rowsToChange.html(superlink).css("display","block");

这看起来可能是一个有效的解决方案(different add method?),但我会更喜欢继续收集对象列表,以便最后一行可以发挥其魔力。

am not i am指出以下情况并非如此 - 关于连接;感谢'我不是我')

似乎add()操作必须连接字符串,因为这似乎是其他人面临的主要问题之一。但是将我的add()语句转换为+ =似乎不起作用。

感谢您查看此内容;

Chrome:18.0.1025.142 m Firefox:11.0 IE:8.0.7600.16385

2 个答案:

答案 0 :(得分:5)

首先观察:add保存前一个元素集。请改为rowsToChange = jQuery.merge(rowsToChange, [$this]);

第二个观察结果:似乎rowsToChange最终将成为与您调用$.makeArray的元素完全相同的元素集。为什么不保存原始集?

答案 1 :(得分:0)

DCoder显示了如果使用for循环,如何将信息合适地合并在一起。但是,如果您来到这里并使用.each()循环,请使用以下内容。

主要区别在于根据'this'的结构,括号是不必要/必要的。似乎普遍认为.each() 至少比原始javascript for循环略慢。 (evidence from 2009)(timing test_copied from question above

var $this, rowsToChange = $([]);
// slower than a for loop
$("[id^=stackLocatorLinkFillUp]:gt("+(uniqueID-1)+")").each( function() {
    // If statements <removed> that decide whether or not to include in the new container
    $this = $(this); // probably unnecessary under most situations
    rowsToChange = jQuery.merge(rowsToChange, $this);
});

对已删除的if语句决定的新子组的每个部分进行操作!

rowsToChange.html("...");

感谢所有观看过这个问题的人,花时间回答,投票等等!