Large selection lists and fast string concatenation in JavaScript

thumbnail
 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).

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

This example uses the createElement and add 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.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

This example uses the innerHTML property to create a selection list with 2000 options:
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

  • Justin

    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("") +
    "";

    February 4, 2010 - 3:52 am
  • Justin

    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>&ltoption>" +
    selectArr.join("</option>&ltoption>") +
    "</select>&lt/option>";

    February 4, 2010 - 3:54 am
  • derek

    Encouraging that IE8 seems to have fixed some of this.

    February 4, 2010 - 6:19 pm
  • 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);

    February 6, 2010 - 4:36 am

1 Trackback

  1. uberVU - social comments