[英]jQuery: add() performance; is there a better way?
我想要做的:将页面上的所有类似元素(某种类型)分组到一个 object 中,我可以稍后对其进行迭代——或者对其中的每个元素应用彻底的更改。
我的代码成功完成了给定的任务,但是当元素数量增加到 200-300+ 时,性能急剧下降,用户已经注意到了。 我已经隔离了有问题的代码行,想知道是否有另一种方法可以解决同样的问题。
add() function 似乎是基于我放置在它们周围的计时器的有问题的操作。 起初,执行该操作所需的时间是 .001,但会一直增加到元素数量达到 300,并且每个额外的元素需要 ~.1 秒,并且继续减慢。
我已经研究( 以及更多)jQuery 性能增强能力并实施了其中一些(即 3),但它们没有给我任何有意义的性能提升。 令人惊讶的是,对于 Firefox(对 add() 的 300 多次调用),此代码在 1 秒 (.) 内执行,而 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&ccLocale=PERIODICAL</div>,
...
]
最终我按如下方式处理所有这些(我喜欢: 的简单性):
var superlink = "...new <a> goodness to display for all elements...";
rowsToChange.html(superlink).css("display","block");
这看起来可能是一个有效的解决方案( 不同的添加方法? )但我更愿意继续将对象列表收集在一起,以便最后一行可以发挥其魔力。
(不是我被指出以下是不正确的——关于串联;谢谢“不是我”)
似乎 add() 操作必须连接字符串,因为这似乎是其他人面临的主要问题之一。 但是将我的 add() 语句转换为 += 看起来并不奏效。
感谢您查看此内容;
铬:18.0.1025.142 m Firefox:11.0 IE:8.0.7600.16385
第一个观察: add
保存了之前的元素集。 试试rowsToChange = jQuery.merge(rowsToChange, [$this]);
反而。
第二个观察:似乎rowsToChange
最终将成为与您调用$.makeArray
的元素集完全相同的元素集。 为什么不只保存原始集?
DCoder 展示了在使用for
循环时如何适当地将信息合并在一起。 但是,如果您来到这里并使用.each()
循环,请使用以下内容。
主要区别在于括号是不必要的/必要的,具体取决于'this'
的结构。 人们似乎也普遍认为.each()
至少比原生的 javascript for
循环慢一点。 ( 2009 年的证据)( 从上面的问题中复制的时间测试)
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("...");
感谢所有查看问题、花时间回答、投票等的人!
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.