简体   繁体   中英

Replace element HTML faster in jQuery

I am populating a list with about 25,000 items, using code like this:

var html = "";
for(var i = 0; i < reallyLongArray.length; i++) {
   html += "<li><a href='#'>Hi</a></li>";
}
$("#list ol").html(html);

Somewhat to my surprise, I used a profiler and found out that the bottleneck in my code was not the loop that iterated thousands of times, but setting the html of the list to the string. This usually takes about 5-10 seconds on my computer, which is an order of magnitude too slow.

Is there a way to do this that is significantly faster, ie, at least 10 times faster?

Wrap the html in a single item. When jQuery builds elements from a string, it adds all top level items by iterating them. If you wrap the list items in a single element, it should go much faster because it only has to add 1 top level element to the dom.

var html = "<ul>";
// your loop...
var html += "</ul>";
// add list html to list container

Aside from directly using innerHTML :

$("#list ol").get(0).innerHTML = html;

...and trying the "stringbuffer" technique:

var html = [];
for(i = 0; i < reallyLongArray.length; i++) {
   html.push("<li><a href='#'>Hi</a></li>");
}
$("#list ol").html(html.join(''));

...not really.

Using DOM methods to create it should work faster:

var list = ("#list ol");
for(i = 0; i < reallyLongArray.length; i++) {
    $(document.createElement('li'))
        .append($(document.createElement('a'))
            .text('Hi')
            .attr({href: 'foobar'})
        )
        .appendTo(list);
}

edit : Actually, using DocumentFragment should make this even faster:

var fragment = document.createDocumentFragment();

for(i = 0; i < reallyLongArray.length; i++) {
    fragment.appendChild($(document.createElement('li'))
        .append($(document.createElement('a'))
            .text('Hi')
            .attr({href: 'foobar'})
        )
        .get(0)
    );
}
$('list ol').append(fragment);

You might also want to clear() the <ol> before adding the elements to it

another edit I've created a jsperf test at http://jsperf.com/insert-html-vs-dom-manipulation - both those versions are slower than setting the innerHTML (because jQuery is used to create the elements). Using dom maniuplation with native methods is much faster than setting the HTML, BUT the fastest way, by a large margin, is using DOM manipulation with DocumentFragment without jQuery, using native methods .

$.grep(ComboBoxData, function (e) {

        if (e.Text.toLowerCase().indexOf(TextBox) != -1 || e.ID.toLowerCase().indexOf(TextBox) != -1) {

            Show = true;
            Result += "<li hdnTextID='" + hdTextID + "' onclick='Select(this," + TextBoxID + ")' onmouseover='triggerTheli(this)' HdntriggerID='" + e.HdntriggerID + "' postBack='" + e.TriggerPostBack + "' Event='" + e.EventName + "' HdnID='" + e.hdnID + "' SelectedValue='" + e.ID + "' style='background:" + Color + "'><a>" + e.Text + "<p> " + e.Description + " </p></a></li>";
            if (Color == "#eff3ec")
                Color = "#fff";
            else
                Color = "#eff3ec";
        }

    });

a good example of mine

This will speed it up by quite a bit. String concatenation can take a long time when used a lot because of what happens "under the hood".

$(document).ready(function(){
var html = new Array();
for(i = 0; i < reallyLongArray.length; i++) {
   html[i] = "<li><a href='#'>Hi</a></li>";
}
document.getElementById('list').getElementsByTagName('ol')[0].innerHTML = html.join("");

});

One thing to just note here, is that when doing an iteration of 25,000, it will be difficult to reduce the time down to milliseconds if you are inserting a large number of records. This happens especially in IE as it parses each new element before inserting it. Building a "pager" and caching the items you are going to insert will significantly speed that up.

Array joins are faster than string manipulation.

var html[];

for(i = 0; i < reallyLongArray.length; i++) {
    html.push(string);
}
$(selector).html(html.join(''));

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM