Comparison of Multiple Select Box Population Performance
I was recently working on developing a web application for a team project at school, when I ran into a little problem. We had a list of 1881 items to put in a select box. That, in itself, was a no-brainer. The problem was, we wanted to have 10 select boxes on this page, each with all 1881 items in it.
So, since I was using JSP, I pulled the entire list of OPTION tags out and stuck it in a separate file, then used the include directive, like:
< %@ include file=”optionList.jsp” % >
inside each of the 10 sets of SELECT tags, so the list was only stored in one place. However, this optionList.jsp file was 59KB, and this page needed to load reasonably fast, despite being served off my home server with a cable modem, and viewed at school with a flaky, unreliable wireless connection. Therefore, a page with over 590KB worth of text/html was just not going to work.
Well, I’ve dealt with manipulating select boxes using JavaScript before, so I decided to try putting all the options into an array of strings, and looping through each select box, and each element of the option array, to add all the options. Well, this worked fine in Firefox, but in IE, it took a ridiculous amount of time (roughly 2 minutes). With that kind of performance, we might as well just load the 590+ KB original page!
So, I did some research into javascript optimization, and explored the W3C DOM spec extensively. I created about 10 different methods of populating the select boxes, and ran each of them with timing code around them, in IE and Firefox. Eventually, I found a solution that performed reasonably well in IE and Firefox, and used it for the team project.
The key lines of code are:
var tmp = document.getElementById(’selectBox_0′).cloneNode(true);
// …
var selectN = document.getElementById(’selectBox_’ + pickNum);
// …
selectN.parentNode.replaceChild(tmp, selectN);
Basically, I created the first select box one option at a time, then cloned that select box object (with the ‘true’ parameter, to clone all child nodes as well) and replaced all the other select boxes with the clones. Then, I set some properties on the clones to make them unique (IDs, default blank options, etc). Dramatically faster than the other.
I’ve put together a benchmark page to test/demonstrate the original method of populating the select boxes (adding one option at a time, to one select box at a time), versus the method I found that worked so well. Then I ran the benchmark on several browsers, on several computers, and had some friends and co-workers try it, too. You can find the benchmark page here:
http://www.oatmealcookies.org/blogdl/
performance/MultiSelectPerformance.html
The benchmark results, as I’ve recorded them so far, can be found in a comma-delimited text file at:
http://www.oatmealcookies.org/blogdl/
performance/MultiSelectPerformance.csv
I recently found out that Opera 8.02 works about as fast as Firefox, even faster in some cases. I was impressed that the code that I’d tested thoroughly in IE and Firefox (but not Opera) actually RAN without errors, but the fact that it ran so fast was pretty cool.
Please feel free to run the benchmark and send me your results! The way that these measurements have been recorded is:
Click ‘Run All’.. when tests are complete (ranges from 12 seconds to 5 minutes, depending on browser and platform), click ‘Save Data’, which populates a textarea at the bottom of the page, and selects it, so you can then copy it to your clipboard and post it in a comment on this blog entry. Please include all fields that are in that CSV file, including browser versions, OS, processor speed, etc.


Leave a Reply