简体   繁体   English

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

[英]jQuery: add() performance; is there a better way?

What I want to do: Group all the like elements on a page (of a certain kind) into an object which I can later iterate on -- or apply sweeping changes to every element within.我想要做的:将页面上的所有类似元素(某种类型)分组到一个 object 中,我可以稍后对其进行迭代——或者对其中的每个元素应用彻底的更改。

My code is successful at accomplishing the given task but when the number of elements grows to 200-300+ then the performance drastically drops off and users have noticed.我的代码成功完成了给定的任务,但是当元素数量增加到 200-300+ 时,性能急剧下降,用户已经注意到了。 I have isolated the offending lines of code and want to know if there is another way of accomplishing the same problem.我已经隔离了有问题的代码行,想知道是否有另一种方法可以解决同样的问题。

The add() function appears to be the problematic operation based on timers I have placed around them. add() function 似乎是基于我放置在它们周围的计时器的有问题的操作。 At first the time required to perform the operation is.001 but grows until the number of elements reaches 300 and it takes ~.1 of a second for each additional element AND continues slowing down.起初,执行该操作所需的时间是 .001,但会一直增加到元素数量达到 300,并且每个额外的元素需要 ~.1 秒,并且继续减慢。

I have researched ( and more ) for jQuery performance enhancing abilities and have implemented a few of them (namely 3) but they have not given me any meaningful performance increases.我已经研究以及更多)jQuery 性能增强能力并实施了其中一些(即 3),但它们没有给我任何有意义的性能提升。 Amazingly, this code performs within 1 second (.) for Firefox (300+ calls to add()) while Chrome and IE take roughly 10-20x longer or more...令人惊讶的是,对于 Firefox(对 add() 的 300 多次调用),此代码在 1 秒 (.) 内执行,而 Chrome 和 IE 大约需要 10-20 倍或更多...

Here is my code:这是我的代码:

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);
    // **************************
}

The end result looks like this (via Chrome Inspector):最终结果如下所示(通过 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>​,
...
]

Eventually I process all these as follows (which I love the simplicity of:):最终我按如下方式处理所有这些(我喜欢: 的简单性):

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

This looked like it could be a valid solution ( different add method? ) but I would prefer to continue gathering a list of objects together so that the last line can work its magic.这看起来可能是一个有效的解决方案( 不同的添加方法? )但我更愿意继续将对象列表收集在一起,以便最后一行可以发挥其魔力。

( am not i am pointed out that the following is not true -- regarding concatenation; thanks 'am not i am') 不是我被指出以下是不正确的——关于串联;谢谢“不是我”)

It seems like the add() operation must be concatenating strings since that appears to be one of the main problems others face.似乎 add() 操作必须连接字符串,因为这似乎是其他人面临的主要问题之一。 But transforming my add() statement into += doesn't look like it works.但是将我的 add() 语句转换为 += 看起来并不奏效。

Thanks for checking this out;感谢您查看此内容;

Chrome: 18.0.1025.142 m Firefox: 11.0 IE: 8.0.7600.16385铬:18.0.1025.142 m Firefox:11.0 IE:8.0.7600.16385

First observation: add saves the previous element set.第一个观察: add保存了之前的元素集。 Try rowsToChange = jQuery.merge(rowsToChange, [$this]);试试rowsToChange = jQuery.merge(rowsToChange, [$this]); instead.反而。

Second observation: it seems as though rowsToChange will end up being the exact same element set as the one you called $.makeArray on.第二个观察:似乎rowsToChange最终将成为与您调用$.makeArray的元素集完全相同的元素集。 Why not just save the original set?为什么不只保存原始集?

DCoder shows how to appropriately merge the information together if you are using a for loop. DCoder 展示了在使用for循环时如何适当地将信息合并在一起。 However, if you come here and are using a .each() loop, use what follows.但是,如果您来到这里并使用.each()循环,请使用以下内容。

The main difference is that brackets are unnecessary / necessary depending on the structure of 'this' .主要区别在于括号是不必要的/必要的,具体取决于'this'的结构。 It also seems to be generally accepted that .each() is at least slightly slower than the native javascript for loop.人们似乎也普遍认为.each()至少比原生的 javascript for循环慢一点。 ( evidence from 2009 ) ( timing test_copied from question above ) 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);
});

Operate on every piece of the new sub-group decided upon by the removed if statements!对由删除的 if 语句决定的新子组的每个部分进行操作!

rowsToChange.html("...");

Thanks to everyone who viewed the question, took the time to answer, voted it up, etc.!感谢所有查看问题、花时间回答、投票等的人!

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM