简体   繁体   English

我应该使用jQuery.each()吗?

[英]Should I use jQuery.each()?

I'm doing very frequent iterations over arrays of objects and have been using jQuery.each(). 我正在对对象数组进行非常频繁的迭代,并且一直在使用jQuery.each()。 However, I'm having speed and memory issues and one of the most called methods according to my profiler is jQuery.each(). 但是,我有速度和内存问题,根据我的探查器,最常调用的方法之一是jQuery.each()。 What's the word on the street about its performance? 街上有什么关于它的表现的话? Should I switch to a simple for loop? 我应该切换到简单的for循环吗? Of course I'm fixing the many issues in my own code too. 当然,我也在修复我自己的代码中的许多问题。

This article (#3) ran some performance tests and found that the jQuery .each function was about 10x as slow as the native javascript for loop. 本文 (#3)运行了一些性能测试,发现jQuery .each函数的速度是本机javascript for循环的10倍。

From 10 Ways to Instantly Increase Your jQuery Performance - 3. Use For Instead of Each 10种方式立即提高您的jQuery性能 - 3.使用而不是每个
Using Firebug , it's possible to measure the time each of the two functions takes to run. 使用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'); 

The above results are 2ms for native code, and 26ms for jQuery's "each" method. 对于本机代码,上述结果为2ms,对于jQuery的“each”方法,结果为26ms。 Provided I tested it on my local machine and they're not actually doing anything (just a mere array filling operation), jQuery's each function takes over 10 times as long as JS native "for" loop. 如果我在我的本地机器上测试它并且它们实际上没有做任何事情(仅仅是一个数组填充操作),jQuery的每个函数都需要JS本地“for”循环的10倍。 This will certainly increase when dealing with more complicated stuff, like setting CSS attributes or other DOM manipulation operations. 在处理更复杂的东西时,这肯定会增加,例如设置CSS属性或其他DOM操作操作。

The source code for jQuery's each is as follows (Thank you John Resig and MIT License): jQuery的源代码分别如下(感谢John Resig和MIT License):

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;
}

As you can trace and see, in most cases it is using a basic for loop where the only overhead is really just the callback itself. 正如您可以跟踪和查看的那样,在大多数情况下,它使用的是基本的for循环,其中唯一的开销实际上只是回调本身。 Shouldn't make a difference in performance. 不应该在性能上有所作为。

EDIT: This is with the realization that selector overhead has already occurred and you are given a populated array object . 编辑:这是因为已经发生了选择器开销,并且您获得了一个填充的数组object

This method should give you a dramatic speed improvement. 这种方法应该可以显着提高速度。

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";
}

Caching will also improve performance. 缓存还可以提高性能。

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

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

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

In use: 正在使用:

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";
    }
}

One way to make sure you are getting the most out of jquery is to store the returned array of results in a variable rather than re-traversing the DOM everytime you need to get something. 确保从jquery中获得最大收益的一种方法是将返回的结果数组存储在变量中,而不是每次需要获取某些内容时重新遍历DOM。

Example of what NOT to do: 什么不做的例子:

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

Better practice: 更好的做法:

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

Using native functionality will generally be faster than an abstraction, such as JQuery.each() method. 使用本机功能通常比抽象更快 ,例如JQuery.each()方法。 However, the JQuery.each() method is easier to use and requires less coding on your part. 但是,JQuery.each()方法更易于使用,并且您需要更少的编码。

Truthfully, neither one is the right or wrong choice without any context. 说实话,没有任何背景,没有一个是正确或错误的选择。 I'm of the oppinion that we should be writing easier code first, assuming it's good/legilble/clean code. 我认为我们应该首先编写更简单的代码,假设它是好的/合法的/干净的代码。 If you come into a situation, such as the one you're describing, where there's a noticeable lag, than it's time to find out where your bottlenecks are and write faster code. 如果你遇到一种情况,例如你所描述的情况,那里存在明显的滞后,那么就应该找出你的瓶颈所在并编写更快的代码。

Replacing the JQuery.each() method in these scenarios might help, however, having not seen your code, it's possible you have bottlenecks unrelated to the JQuery method. 在这些场景中替换JQuery.each()方法可能会有所帮助,但是,如果没有看到您的代码,则可能存在与JQuery方法无关的瓶颈。

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

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