34

我对对象数组进行了非常频繁的迭代,并且一直在使用 jQuery.each()。但是,我遇到了速度和内存问题,根据我的分析器,最常调用的方法之一是 jQuery.each()。街上对它的表现有什么看法?我应该切换到简单的 for 循环吗?当然,我也在自己的代码中解决了许多问题。

4

5 回答 5

29

这篇文章(#3) 运行了一些性能测试,发现 jQuery .each 函数的速度大约是原生 javascript for 循环的 10 倍。

立即提高 jQuery 性能的 10 种方法 - 3. 使用 For 而不是每个使用
Firebug 可以测量两个函数中的每一个运行所需的时间。

var array = new Array ();
for (var i=0; i<10000; i++) {
    array[i] = 0;
}

console.time('native');
var l = array.length;
for (var i=0;i<l; i++) {
    array[i] = i;
}
console.timeEnd('native');

console.time('jquery');
$.each (array, function (i) {
    array[i] = i;
});
console.timeEnd('jquery');

以上结果对于原生代码是 2ms,对于 jQuery 的“each”方法是 26ms。如果我在本地机器上对其进行了测试,并且它们实际上并没有做任何事情(只是一个数组填充操作),jQuery 的每个函数所占用的时间是 JS 原生“for”循环的 10 倍以上。当处理更复杂的事情时,这肯定会增加,比如设置 CSS 属性或其他 DOM 操作操作。

于 2009-12-10T20:12:53.667 回答
15

jQuery 的每个源代码如下(感谢 John Resig 和 MIT 许可证):

each: function( object, callback, args ) {
    var name, i = 0, length = object.length;

    if ( args ) {
        if ( length === undefined ) {
            for ( name in object )
                if ( callback.apply( object[ name ], args ) === false )
                    break;
        } else
            for ( ; i < length; )
                if ( callback.apply( object[ i++ ], args ) === false )
                    break;

    // A special, fast, case for the most common use of each
    } else {
        if ( length === undefined ) {
            for ( name in object )
                if ( callback.call( object[ name ], name, object[ name ] ) === false )
                    break;
        } else
            for ( var value = object[0];
                i < length && callback.call( value, i, value ) !== false; value = object[++i] ){}
    }

    return object;
}

如您所见,在大多数情况下,它使用的是基本的 for 循环,其中唯一的开销实际上只是回调本身。应该不会影响性能。

编辑:这是因为选择器开销已经发生并且你得到了一个填充的数组object

于 2009-12-10T20:13:55.193 回答
8

这种方法应该会给您带来显着的速度提升。

var elements = $('.myLinks').get(), element = null;
for (var i = 0, length = elements.length; i < length; i++) {
    element = elements[i];
    element.title = "My New Title!";
    element.style.color = "red";
}

缓存也将提高性能。

function MyLinkCache() {
    var internalCache = $('.myLinks').get();

    this.getCache = function() {
        return internalCache;  
    }

    this.rebuild = function() {
        internalCache = $('.myLinks').get();
    }
}

正在使用:

var myLinks = new MyLinkCache();

function addMyLink() {
    // Add a new link.
    myLinks.rebuild();
}

function processMyLinks() {
    var elements = myLinks.getCache(), element = null;
    for (var i = 0, length = elements.length; i < length; i++) {
        element = elements[i];
        element.title = "My New Title!";
        element.style.color = "red";
    }
}
于 2009-12-10T20:12:09.563 回答
7

确保充分利用 jquery 的一种方法是将返回的结果数组存储在变量中,而不是每次需要获取某些内容时都重新遍历 DOM。

不该做的事的例子:

$('.myLinks').each(function(){
    // your code here
});
$('.myLinks').each(function(){
    // some more code here
});

更好的做法:

var myLinks = $('.myLinks');
myLinks.each(function(){
    // your code here
});
myLinks.each(function(){
    // some more code here
});
于 2009-12-10T20:08:19.367 回答
6

使用本机功能通常比抽象更快,例如 JQuery.each() 方法。但是,JQuery.each() 方法更易于使用,并且您需要的编码更少。

说实话,没有任何背景,谁都不是正确或错误的选择。我认为我们应该首先编写更简单的代码,假设它是好的/易读的/干净的代码。如果您遇到一种情况,例如您所描述的情况,存在明显的滞后,那么是时候找出瓶颈所在并编写更快的代码了。

在这些场景中替换 JQuery.each() 方法可能会有所帮助,但是,由于没有看到您的代码,您可能遇到与 JQuery 方法无关的瓶颈。

于 2009-12-10T21:22:52.723 回答