0

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?

inControl
  • 2,215
  • 4
  • 24
  • 39
  • When you say "crash", do you actually mean "freeze"? – Guffa Oct 04 '12 at 09:42
  • yes freeze and windows some times comes up with a pop up as in this program is not responding etc. it does the same thing on every computer tested on. – inControl Oct 04 '12 at 09:43

4 Answers4

2

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

Community
  • 1
  • 1
Guffa
  • 687,336
  • 108
  • 737
  • 1,005
  • The code you gave me works, but I stil have the same problem. – inControl Oct 04 '12 at 09:50
  • Sorry my problem is sort of fixed, but whenever I empty a very large list of options it lags/freezes/crashes not when filling one. – inControl Oct 04 '12 at 09:59
  • Have you tried emptying that option field? because it freezes/crashes for me on that. – inControl Oct 04 '12 at 10:13
  • Sorry the problem only seems to be in mozilla firefox – inControl Oct 04 '12 at 10:15
  • @inControl: Tearing down objects take a long time in any browser, a lot longer than creating them. Removing 10000 options take about 1.5 seconds in Firefox on my computer, but doubling the number of options more than doubles the time, and after about 33000 options the times start to go up dramatically. – Guffa Oct 04 '12 at 10:38
0

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;
};
Community
  • 1
  • 1
Zahid Riaz
  • 2,879
  • 3
  • 27
  • 38
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);
tranceporter
  • 2,241
  • 1
  • 21
  • 23
0

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.

ChuckE
  • 5,610
  • 4
  • 31
  • 59