03.23.2004 - getElementsByName vs. getElementById
I was first made aware of the painful slowness of document.getElementsByName when I was writing Web Paint. Looping over 1,024 div elements using this method was so slow that I often worried that my browser was going to lock up and possibly explode from the exertion. To compensate, I ended up giving each "pixel" a unique ID and using document.getElementById. The resulting increase in speed of execution was astonishing.
Another project that I am currently working on reminded me of this, so I decided to write a little benchmark script to see just how much of a real difference there was. The test works like this: on load, a javascript function creates one hundred DIV elements that share a like name and id attribute of "mDiv". It also creates another one hundred div elements id'd "nDiv" + i, so nDiv0 through nDiv99.
Two buttons call two seperate functions. The first loops over the length of document.getElementsByName("mDiv") and sets each DIV element's innerHTML property to a zero length string, i.e., "". The second button calls a nearly identical function that loops from 0 to 99 and sets each nDiv+i element's innerHTML property to a zero length string.
Each function creates a Date object at its start and another at its finish and then subtracts and alerts the elapsed time. Here are the results on my 1.6GHz P4 with 512MB of RAM running on WinXP:
Browser | getElementsByName | getElementById |
Firefox 0.8 | 120 - 130 ms | 40-80 ms |
Mozilla 1.6 | 90 ms | 30-50 ms |
Opera 7.2 | 290 ms | 270-280 ms |
Netscape 7.02 | 100-110 ms | 40-70 ms |
Konqueror 2.2.2* | 360-721 ms | 253-400 ms |
MSIE 6 | 20 ms | 30 ms |
As you can see, getElementById is always faster than getElementsByName, except in MSIE. Now, assuming there is no flaw in my code, what could the reason for this be? Especially considering that I'm expecting the javascript parser to figure out that I mean "nDiv63" when I say "nDiv"+i, which just by nature really should be awfully slow.
My first thought on this was that getElementsByName could be a programmatic alias to document.all considering IE's implementation of getElementsByName. However, the same test using document.all is slower at 50 ms. So -- I have no idea what the story is here. Have a look at the benchmark page for yourself and see what your results are, and if you've any insight feel free to post your thoughts.
* Konqueror test was run on an 800MHz box with 256MB of RAM. I really only posted it's results as a reminder to myself that my linux box is in horrible condition and that I ought to upgrade it.
Posted by michel on April 16, 2004 @ 5:35 am
thats because you are querying the document every loop to find the length to go to...
so just dont and you will find that you are now faster with getElementsByName or at least you are comparing the two fairly
function benchmarkGEBN() {
sTime = new Date();
sTime = sTime.getTime();
var totlen=document.getElementsByName("mDiv").length
for(i=0;i<totlen;i++) {
document.getElementsByName("mDiv")[i].innerHTML = "";
}
fTime = new Date();
fTime = fTime.getTime();
alert(fTime-sTime + " ms to execute");
}
Posted by masuel on October 29, 2004 @ 3:52 am
At any rate, changing that conditional to a literal value of 100 made no difference - it's still slower.
Posted by Steve on November 2, 2004 @ 4:05 pm
Well for me if you had the document.getElementsByName("mDiv").length in the head of the for loop it was definaly called ever time round. Hence twice as many quires to the document tree in javascript...
I am quite surprised if you got identical timings when removing this call from the loop. The function inside the loop (ie document.getElementsByName("mDiv")[i].innerHTML = ""; ) must be overwhelmingly slow.
intersting.
I can't repeat you results as I don't have access to IE, for reference I was using konqueror in my tests.
Posted by masuel on November 11, 2004 @ 8:10 am
Posted by Pete on April 11, 2005 @ 5:38 pm
Posted by joe t. on July 8, 2005 @ 2:45 pm
Posted by joe t. on July 8, 2005 @ 2:45 pm
var collection = document.getElementsByName('someName');
var len = collection.length;
for (var i=0; i<len; i++)
{
var element = collection[i];
}
I bet it's a lot faster then!
-Stijn
Posted by Stijn on August 2, 2005 @ 10:56 am
Comments have been closed for this post.