slayeroffice - web experiments gone horribly awry

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:

BrowsergetElementsByNamegetElementById
Firefox 0.8120 - 130 ms40-80 ms
Mozilla 1.690 ms30-50 ms
Opera 7.2290 ms270-280 ms
Netscape 7.02100-110 ms40-70 ms
Konqueror 2.2.2*360-721 ms253-400 ms
MSIE 620 ms30 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.

on macosx 10.3.2, 867mhz G4, using safari 1.2.1, my results are: getElementsByName : 28-32 ms (4 tries) getElementByID: 7-12 ms (4 tries)
Posted by michel on April 16, 2004 @ 9:35 am
Urm....

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 @ 7:52 am


I query the document for the object in both functions - that was kind of the point. Your code changes it to set totlen to the length of the object array, but that makes no difference as it still resolves to a number, and it isnt querying for that number on each iteration of the loop, only when the loop instantiates.

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 @ 9:05 pm


Oh...

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 @ 1:10 pm


Perhaps it is because getElementsByName() is broken in IE, and never returns a collection of named objects like it should - it *has* to faster returning null that something real, right? At least, this is my experience; if you can show me how to make this function work, I'll send you a puppy.
Posted by Pete on April 11, 2005 @ 9:38 pm
i found this article trying to solve a vaguely similar problem, and according to the information available, getElementByName isn't "broken" in IE, it's just more compliant with the HTML 4.01 spec. Amazing to have "IE" and "compliant" in the same sentence, but there it is. Anyway, sorry, just happened to stumle across this page looking for help on something mostly unrelated.
Posted by joe t. on July 8, 2005 @ 6:45 pm
heh, oops. ... http://jszen.blogspot.com/2004_07_01_jszen_archive.html
Posted by joe t. on July 8, 2005 @ 6:45 pm
Ofcourse if you use the function as intended, you don't call it again and again in the head of the for loop and you don't even call it in the body of the loop!

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 @ 2:56 pm


Comments have been closed for this post.