简体   繁体   中英

Optimization appending <li> into <ul> with jQuery

I populate a list with search results appending li elements. I update DOM for each result.

for (var i = 0; i < topics.length; i++) {
    $("#searchResults").append(
        $("<li />")
            .append(result.Name)
            .addClass("example")
    );
};

I want to make a group of li elements first and update DOM-tree just once.

I try something like this:

var list = $([]);

for (var i = 0; i < topics.length; i++) {
    list.append(
        $("<li />")
            .append(result.Name)
            .addClass("example")
    );
};

$("#searchResults").append(list);

But div $("#searchResults") is empty.

Where is the problem?

Something like this should be much faster:

var ul = $("<ul />");
for (var i = 0, l=topics.length; i < l; i++) {
   $("<li />", { text: result.Name, "class": "example" }).appendTo(ul);
};
$("#searchResults").append(ul.contents());

By using a document fragment ( $("<ul />") ) and appending to it, then appending at the end, we're not messing with the entire DOM each append. Also we're not repeatedly selecting #searchResults each loop...or checking .length would could also be expensive.

Note: this method still uses the DOM to create elements (as opposed to a string), eliminating issues of result.Name having HTML that could screw things up, etc.

All previous solutions still suffer from recalculating, painting and layout for every single element we add.

Instead of appending the elements directly to the document when they are created, append them to the DocumentFragment instead, and finish by adding that to the DOM.

var el;
var i = 0;
var fragment = document.createDocumentFragment();

while (i < 500) {
    el = document.createElement('li');
    el.innerText = '1ist ' + i;
    fragment.appendChild(el);
    i++;  
}

div.appendChild(fragment);

Try just using a string. Add all your li 's to a string and then put them into the innerHTML of the searchResults div.

var list = '';

for (var i = 0; i < topics.length; i++) {
    list +="<li class=example>" + result.Name + "</li>";
}

$("#searchResults").innerHTML = list;

If you are looking for efficacy this is probably better because you are not using the DOM engines a lot. (although unless you are adding hundreds of li 's it is probably insignificant anyway.

Creating DOM elements on the fly will usually be slower than just using innerHTML (or a wrapper around that). Also, concatenating string with + will usually be slower than using Array.join('') .

In the end, I suspect something like this would be the fastest:

var list = [];

for (var i = 0; i < topics.length; i++) 
    list.push("<li class=example>",topics[i].Name,"</li>");

$("#searchResults").html(list.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