Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Does storing selected/found elements in variable increase performance?

I created a jQuery plugin to modify my navigation. Unfortunately I have to access and modify almost all child elements such as <ul>, <li>, <a> and so forth. Those elements are then needed between one and four times.

Should I store them all in variables or should I access them like $('.my-nav').find('li') or $('.my-nav').find('li') when needed?

It just seems like a waste of memory to have 5 variables for maybe 25 lines of code. But I don't know if this is a acceptable trade-off for more performance.

I created a Fiddle to illustrate what is meant: http://jsfiddle.net/Yj35Q/2/

like image 370
John B. Avatar asked May 07 '12 21:05

John B.


3 Answers

Always good practice to cache your nodes. You can also benchmark yourself using http://jsperf.com/

You don't really need to worry about how much storage space variables need unless you are storing a massive DOM tree or something. Much more relevant the amount of work the JS engine has to do to locate the nodes.

EDIT
or even better, you can find an existing test case someone else has already created
http://jsperf.com/ns-jq-cached/4

like image 165
gotofritz Avatar answered Oct 18 '22 16:10

gotofritz


It's certainly wise to cache your DOM elements where appropriate, whether you're using jQuery or not.

But this question got me thinking that maybe we should have a plugin to help with this. I searched around and couldn't find one.

So I wrote one really quick. It's a lazy loading jQuery selector...

(function($){
    var cachedObjects = new Array();

    $.lazy = function(selector) {
        if (typeof selector != "string" || arguments.length > 1) 
            return $.apply(this, arguments);

        var o = cachedObjects[selector];
        if (o == undefined)
        {
            o = $(selector);
            cachedObjects[selector] = o;
        }

        return o;
    };
})(jQuery);

You'd use it like this...

$.lazy('.my-nav').show();

Let me know if I've overlooked anything. But I believe this would be good to use whenever the elements you're selecting are static and are never added or removed dynamically.

UPDATE

I've changed the code to make this more efficient. And I've added a line to return $(selector) when the selector is not a string. So the caching will only work when the selector is a string.

UPDATE #2

Now it'll return $.apply(this, arguments) when you're not simply passing a string, per jfriend00's suggestion.

like image 40
Steve Wortham Avatar answered Oct 18 '22 15:10

Steve Wortham


Within the same function, I will cache the results of a DOM search in a local variable so I never have to do the same DOM search more than once in the same function. For most functions this will not be needed, but it's easy and safe to put the result in a local variable only for the duration of the function so I think it's a good habit.

I will usually NOT cache DOM nodes into global variables simply because I try to avoid global variables and it is rarely a performance issue to retrieve the DOM node when needed for a particular function. Another reason to avoid having DOM references in global variables is that if a particular DOM node gets removed from the DOM and you intend for it to be garbage collected, if there is a reference to it in a global variable, the DOM node will not be garbage collected and could lead to a memory leak.

There are some cases where I am repeatedly looking up the same DOM node (like on a timer) where I will cache the DOM node into a non-global variable in a function closure and then use that variable locally. But, I find cases where this is needed to be rare.

like image 2
jfriend00 Avatar answered Oct 18 '22 16:10

jfriend00