Sometimes a selection list needs to be filled dynamically depending on the state of another control
(e.g. when the user selects a country and a selection list must contain the cities in this country,
or when the user selects a singer and a selection list must contain his/her songs).
Unfortunately, the usual way of creating a selection list with a large number of items is quite slow in Internet Explorer. In the followings, you can find solutions and speed tests for the problem (the speed test was run on an average computer).
Unfortunately, the usual way of creating a selection list with a large number of items is quite slow in Internet Explorer. In the followings, you can find solutions and speed tests for the problem (the speed test was run on an average computer).
Example 1, the usual way.
This example uses the createElement and appendChild methods to create a selection list with 2000 options:
var select = document.createElement ("select"); for (var i = 0; i < 2000; i++) { var option = document.createElement ("option"); option.text = i; select.appendChild (option); } container.appendChild (select); |
||||
|
Speed test:
Browser | Time |
---|---|
IE 6 | 1802 ms |
IE 7 | 1953 ms |
IE 8 | 594 ms |
Firefox | 90 ms |
Opera | 31 ms |
Safari | 5 ms |
Remarks:
The example does not work properly in Internet Explorer, it creates a selection list with 2000 empty options.
Example 2
var select = document.createElement ("select"); for (var i = 0; i < 2000; i++) { var option = document.createElement ("option"); option.text = i; select.options.add (option); } container.appendChild (select); |
||||
|
Speed test:
Browser | Time |
---|---|
IE 6 | 2703 ms |
IE 7 | 3000 ms |
IE 8 | 984 ms |
Firefox | 366 ms |
Opera | 234 ms |
Safari | 68 ms |
Example 3
var select = "<select>"; for (var i = 0; i < 2000; i++) { select += "<option>" + i + "</option>"; } select += "</select>"; container.innerHTML += select; |
||||
|
Speed test:
Browser | Time |
---|---|
IE 6 | 70 ms |
IE 7 | 78 ms |
IE 8 | 15 ms |
Firefox | 59 ms |
Opera | 16 ms |
Safari | 17 ms |
The solution implemented by Example 3 works much more faster than the previous ones in Internet Explorer and it is also fast in other browsers.
Unfortunately, the processing time grows drastically for greater number of options in Internet Explorer.
This behavior is independent of the select and option elements, it is based on the speed of string concatenations.
But how can strings be concatenated faster?
The following examples answer that question.
Example 4
This example same as the previous one, but it creates a selection list with 8000 options:
var select = "<select>"; for (var i = 0; i < 8000; i++) { select += "<option>" + i + "</option>"; } select += "</select>"; container.innerHTML += select; |
||||
|
Speed test:
Browser | Time |
---|---|
IE 6 | 961 ms |
IE 7 | 1781 ms |
IE 8 | 47 ms |
Firefox | 242 ms |
Opera | 47 ms |
Safari | 67 ms |
Example 5
This example creates an array from the substrings first then concatenates the array elements with the join method:
var selectArr = new Array (); selectArr.push ("<select>"); for (var i = 0; i < 8000; i++) { selectArr.push ("<option>" + i + "</option>"); } selectArr.push ("</select>"); container.innerHTML += selectArr.join (""); |
||||
|
Speed test:
Browser | Time |
---|---|
IE 6 | 280 ms |
IE 7 | 172 ms |
IE 8 | 47 ms |
Firefox | 240 ms |
Opera | 62 ms |
Safari | 70 ms |
4 Comments
You can reduce the number of concatinations further with:
var selectArr = new Array();
for (var i = 0; i < 8000; i++) {
selectArr.push(i);
}
container.innerHTML +=
"" +
selectArr.join("") +
"";
Well that mangled my comment, should have been:
var selectArr = new Array();
for (var i = 0; i < 8000; i++) {
selectArr.push(i);
}
container.innerHTML +=
"<select><option>" +
selectArr.join("</option><option>") +
"</select></option>";
Encouraging that IE8 seems to have fixed some of this.
I did some work on this as well. Here's some things I found:
1. This is very fast
var citySelect = document.getElementById('city_id'),
selectOption = null,
ops = "",
c = [],
docFrag = null;
docFrag = document.createDocumentFragment();
selectOption = document.createElement('option');
for (var city in cities) {
ops = selectOption.cloneNode("false");
ops.value = city;
ops.text = cities[city];
docFrag.appendChild(ops);
};
citySelect.appendChild(docFrag.cloneNode("true"));
2. Removing the element from the DOM and adding it back in is very fast (of course, you lose your attached events)
var citySelect = document.getElementById('city_id'),
c = document.getElementById('city'),
selectOption = null,
ops = "";
selectBox = document.createElement("select");
selectBox.id = 'city_id';
selectBox.name = 'name_id';
selectOption = document.createElement('option');
for (var city in cities) {
ops = selectOption.cloneNode("false");
ops.value = city;
ops.text = cities[city];
selectBox.appendChild(ops);
};
c.removeChild(citySelect);
c.appendChild(selectBox);
3. This is extremely quick for clearing the select options array
Array.prototype.splice.call(selectbox.options, 0);