开发者

Should I cache document.getElementById() in a variable or call it everytime?

开发者 https://www.devze.com 2022-12-18 09:27 出处:网络
I\'m having a lot of elements which are generated and referenced (mouseover, clicks, position changes) a lot of times.

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开发者_JS百科.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')]


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


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');


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.


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


I wrote a little JS routine to do some benchmarking on this, with three tests:-

  1. Get value from element into simple variable then assign it repeatedly,
  2. Get value from element with getElementById repeatedly, and
  3. Get element into variable with getElementById, then get from that variable repeatedly.

The test were in ten million iteration loops, and obviously there are many factors that could affect the outcome (the numbers are not even exactly the same on successive runs with a variance of about 10%), but they offer a 'reasonable indication'.

Test 1 - 11 milliseconds

Test 2 - 3983 milliseconds

Test 3 - 3594 milliseconds

A millisecond may not seem long to you, but to your computer, it is almost eternity.

function RunSillySpeedTest(){
var t1,t2,t3,test1,test2,test3
var d,e,f,Msg;

d=new Date();
var t=d.getTime();

//Test 1 - Simple variable assignment
e=document.getElementById('divelement').innerText;
for(var i=0; i<10000000; i++){
    f=e;
}
d=new Date();
t1=d.getTime();
test1=t1-t;

//Test 2 - Repeated getElementById
for(var i=0; i<10000000; i++){
    f=document.getElementById('divelement').innerText;
}
d=new Date();
t2=d.getTime();
test2=t2-t1;

//Test 3 - Stored getElementById
e=document.getElementById('divelement');
for(var i=0; i<10000000; i++){
    f=e.innerText;
}
d=new Date();
t3=d.getTime();
test3=t3-t2;

Msg='<b>Test 1 took '+test1+'ms.<br>Test 2 took '+test2+'ms.<br>Test 3 took '+test3+'ms.<br></b>';
return Msg;

}

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号