views:

330

answers:

6

I'm doing very frequent iterations over arrays of objects and have been using jQuery.each(). However, I'm having speed and memory issues and one of the most called methods according to my profiler is jQuery.each(). What's the word on the street about its performance? Should I switch to a simple for loop? Of course I'm fixing the many issues in my own code too.

+1  A: 

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.

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
});
a432511
Even better practice: do everything in one loop.
ChaosPandion
Or `$('.myLinks').each(function(){a;b;})` `$('.myLinks').each(function(){a;}).each(function(){b;})`.
Gumbo
+1  A: 

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";
    }
}
ChaosPandion
+2  A: 

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.

Jace Rhea
Thanks, that's a good article.
pr1001
+3  A: 

The source code for jQuery's each is as follows (Thank you John Resig and 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. 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.

Justin Swartsel
Have you used IE6?
ChaosPandion
Of course. And like most of us regretfully so. But what is your point specifically? My point is that the heart of "each" is just a for loop. I left the overhead you get from instantiating a jQuery object and selecting dom elements alone.
Justin Swartsel
What I am saying is don't underestimate the overhead of function calls.
ChaosPandion
At the moment, function calls are in fact quite slow in JS. Working on it.
Jason Orendorff
Point well taken. Thanks guys.
Justin Swartsel
A: 

Using native functionality will generally be faster than an abstraction, such as JQuery.each() method. However, the JQuery.each() method is easier to use and requires less coding on your part.

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.

MillsJROSS
+1  A: 

See this:

What's the Fastest Way to Code a Loop in JavaScript?

TheJuice