Frage

When I use the following code

var html = "";
$.map(data.modelTypes, function (item) {
    html+= "<option>" + item.type + "</option>";
});
$("#drowdown").html(html);

there is so much HTML my javascript has to add to the $("#dropdown") element it makes any browser crash for a couple of seconds, in the end it works as it should and fills up the dropdown list but is there anyway of making my browser not crash?

War es hilfreich?

Lösung

Don't concatenate a huge string that has to be parsed, create the actual elements and put in the select:

var options = $.map(data.modelTypes, function (item) {
  return $('<option>', { text: item.type })[0];
});
$("#drowdown").empty().append(options);

Note: You were using the map method as each, you should return the value in the function, then you get an array of the values returned from the map method.

Edit:

Some testing shows that using more plain Javascript instead of using jQuery to loop and create elements makes it twice as fast:

var options = [];
for (var i =0; i < data.modelTypes.length; i++) {
  var o = document.createElement('OPTION');
  o.text = data.modelTypes[i].type;
  options.push(o);
}
$("#drowdown").empty().append(options);

On my computer in Firefox this adds 1000000 option elements in around a second.

Anyhow, if you have so many options, you should probably rethink the UI...

Andere Tipps

StringBuffer usage in javascript in place of string concatenations

String concatenation vs string buffers in Javascript

String concatenation is very slow operation. You have to use string buffer.

function StringBuffer() {
this.__strings__ = new Array;
}

StringBuffer.prototype.append = function (str) {
    this.__strings__.push(str);
};

StringBuffer.prototype.toString = function () {
    return this.__strings__.join("");
};


StringBuffer.prototype.empty = function(){
    this.__strings__.length = 0;
};

Not sure if this will speed up things for you, but why not append to the dropdownlist directly?

$.each(data.modelTypes, function(i, value) {
        $('#drowdown').append($('<option>').text(value).attr('value', value));

Since in your case you have huge list of items, you might want to consider using DocumentFragment. Something on the lines of:

var dropdown= $("#drowdown").empty();

var frag = document.createDocumentFragment();
data.modelTypes.each( function(item) {
    frag.appendChild($('<option>').text(item).attr('value', item));
});

dropdown.append(frag);

First thing is the $.map use. It has vary bad performance when compared with the for from JS. Another thing is the .html use. It is recommended, but if you have a lot of data, the browser JS interpreter will block for a few seconds. Why don't you add one option at a time in your cycle by using append?

for (i = 0; i < data.modelTypes.length; i++) {
  $("#drowdown").append("<option>"+data.modelTypes[i].type+"</option>")); 
}

it's a bit pseudocode, don't know if it compiles, but those are my two cents. Other than that, HTML structure dynamic changes will always be heavy, but you can mitigate that by relying on strings instead of JS vars or jquery objects.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top