views:

326

answers:

4

I'm having a lot of elements which are generated and referenced (mouseover, clicks, position changes) a lot of times.

I have the ID's of those elements at hand. Is it wise to store the document.getElementById(ID) calls in a variable, or is it faster/just as fast/slower to call document.getElementById() everytime?

var app = [];
var app.elements = []; 
//i can store ['id1', 'id2', 'id3']
//OR ['id1' => document.getElementById('id1'), 'id2' => document.getElementById('id2'), 'id3' => document.getElementById('id3')]
+2  A: 

It's certainly faster to store the elements in a variable, but not by a large margin. This is something that's different from case to case and should be adapted for each one individually.

Maybe the biggest factor is legibility, I believe accessing the elements directly is more readable.

theMainButton.style.color = "red";
// vs.
document.getElementById("theMainButton").style.color = "red";
Georg
I'm looking for performance gains here. The code is put away in functions and doesn't need reading :)
Ropstah
ALL code needs reading, unless it is written perfectly the first time, never needs to be modified or extended, never needs new features, and will never need to be understood. :)
Eddie
+4  A: 

You should of course reuse the reference where possible, but you might need to get a new reference in each function body.

Example:

var e1 = document.getElementById('id1');
e1.innerHTML = 'test';
e1.className = 'info';

If you keep references longer, you may find that they no longer work. If you for example get innerHTML for a part of the page and stores it back, all elements in that part is removed and recreated. If you had a reference to one of the elements in that part, that element no longer exists.

// This will recreate all elements inside the 'parent' element:
document.getElementById('parent').innerHTML += 'test';
Guffa
This is a good point, and I'd like to add that you never know who, or what, is going to change a DOM node out from under you. I always favor getting the reference explicitly to reduce bugs and improve readability. If you are handling many nodes in a high performance situation, you might want to assign them to memory instead.
Kris Walker
It will be around 500 items, but they will be managed correctly. I am using jQuery and most of the time the object will be $(jqueryfied) so I can call functions like position(). Does the same thing go for storing the $('#id1') object in memory?
Ropstah
+1  A: 

getElementById returns an element node, which is essentially just a JavaScript object. You can assign this object to a variable, meaning that the variable will point to this object whenever you type that variable at a later stage. So,

var id1 = document.getElementById('id1');

id1 now refers to the DOM element with an id of id1. If no element was found with that id then document.getElementById returns null.

If the elements stay within the DOM and don't get replaced then it makes sense to store them in an array, so that you can reference them as many times as you want without any performance costs.

If it helps, you could create a simple function to do it for you:

function getElementsByIds( /* id1, id2 ... */ ) {

    var elems = [];

    for (var i = 0, l = arguments.length; i < l; i++) {
        elems[i] = document.getElementById(arguments[i]);
    }

    return elems;

}

app.elements = getElementsByIds('id1', 'id2', 'id3');
J-P
+1  A: 

There is no single right answer to this question. It all depends on what you have to work with. If you are working with a page that has massive amount of elements in the DOM tree, it's better to cache the references and reuse them, to speed up look up time. If you are working on a small page, it's better to look up elements on the fly, and minimize memory consumption of the browser.

It also depends on the browsers you are targeting. For example, newer versions of Firefox take a while to fine an element first time, but they cache the reference internally, so next time you are going to look it up, it's going to be almost instant. IE, on the other hand, doesn't cache lookup values, but it's seek time is much faster than Firefox on the first try.

A lot of modern frameworks will cache the elements that you found for you. However, I, personally still prefer to use document.getElementById most of the time. What I do, when I need to cache lookup values is the following:

 function registerElement(id)
 {
     if (!this["get_" + id])
        this["get_" + id] = function() {
            var element = document.getElementById(id);
            this["get_" + id] = function() {return element;};
            return element;
        }
 }

You use this by calling registerElement and passing it an ID of the element. When you need to retrieve the value, you call get_element id you passed and on the first run it will look up the element and cache it, on every consecutive call it will just return cached value.

Ilya Volodin