简体   繁体   English

我应该在变量中缓存 document.getElementById() 还是每次都调用它?

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

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.我手头有这些元素的 ID。 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?document.getElementById(ID)调用存储在变量中是否明智,或者每次调用document.getElementById()是否更快/同样快/慢?

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.例如,如果您获取页面一部分的 innerHTML 并将其存储回来,则该部分中的所有元素都将被删除并重新创建。 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. getElementById返回一个元素节点,它本质上只是一个 JavaScript 对象。 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 . id1现在引用idid1的 DOM 元素。 If no element was found with that id then document.getElementById returns null.如果没有找到具有该id元素,则document.getElementById返回 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.如果元素保留在 DOM 中并且不会被替换,那么将它们存储在数组中是有意义的,这样您就可以根据需要多次引用它们而不会产生任何性能成本。

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.如果您正在处理在 DOM 树中包含大量元素的页面,最好缓存引用并重用它们,以加快查找时间。 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.例如,较新版本的 Firefox 第一次优化元素需要一段时间,但它们会在内部缓存引用,因此下次您要查找它时,它几乎是即时的。 IE, on the other hand, doesn't cache lookup values, but it's seek time is much faster than Firefox on the first try.另一方面,IE 不缓存查找值,但它的查找时间在第一次尝试时比 Firefox 快得多。

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.但是,我个人在大多数情况下仍然更喜欢使用 document.getElementById。 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.您可以通过调用 registerElement 并将元素的 ID 传递给它来使用它。 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.当您需要检索该值时,您调用传递的 get_element id 并在第一次运行时查找元素并缓存它,在每次连续调用时它只会返回缓存值。

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:-我编写了一个小 JS 例程来对此进行一些基准测试,并进行了三个测试:-

  1. Get value from element into simple variable then assign it repeatedly,从元素获取值到简单变量然后重复赋值,
  2. Get value from element with getElementById repeatedly, and使用 getElementById 重复从元素中获取值,以及
  3. Get element into variable with getElementById, then get from that variable repeatedly.使用 getElementById 获取元素到变量中,然后重复从该变量中获取。

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'.测试是在 1000 万次迭代循环中进行的,显然有许多因素会影响结果(连续运行的数字甚至不完全相同,方差约为 10%),但它们提供了“合理的指示”。

Test 1 - 11 milliseconds测试 1 - 11 毫秒

Test 2 - 3983 milliseconds测试 2 - 3983 毫秒

Test 3 - 3594 milliseconds测试 3 - 3594 毫秒

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;

} }

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

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