简体   繁体   English

在 jQuery 中更快地更换元件 HTML

[英]Replace element HTML faster in jQuery

I am populating a list with about 25,000 items, using code like this:我正在使用如下代码填充一个包含大约 25,000 个项目的列表:

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.令我惊讶的是,我使用了一个分析器,发现我的代码中的瓶颈不是迭代数千次的循环,而是将列表的 html 设置为字符串。 This usually takes about 5-10 seconds on my computer, which is an order of magnitude too slow.在我的计算机上,这通常需要大约 5-10 秒,这太慢了一个数量级。

Is there a way to do this that is significantly faster, ie, at least 10 times faster?有没有一种方法可以显着加快速度,即至少快 10 倍?

Wrap the html in a single item.将 html 包装在一个物品中。 When jQuery builds elements from a string, it adds all top level items by iterating them.当 jQuery 从字符串构建元素时,它会通过迭代添加所有顶级项目。 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.如果将列表项包装在单个元素中,它应该 go 更快,因为它只需向 dom 添加 1 个顶级元素。

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

Aside from directly using innerHTML :除了直接使用innerHTML

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

...and trying the "stringbuffer" technique: ...并尝试“stringbuffer”技术:

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:使用 DOM 方法创建它应该更快:

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:编辑:实际上,使用 DocumentFragment 应该会更快:

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您可能还想在添加元素之前clear() <ol>

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).另一个编辑我在http://jsperf.com/insert-html-vs-dom-manipulation创建了一个 jsperf 测试 - 这两个版本都比设置 innerHTML 慢(因为 jQuery 用于创建元素)。 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 .将 dom 操作与本机方法一起使用比设置 HTML 快得多,但在很大程度上,最快的方法是在没有 jQuery 的情况下使用本机方法的 DocumentFragment 进行 DOM 操作

$.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.这里要注意的一件事是,在进行 25,000 次迭代时,如果要插入大量记录,将很难将时间减少到毫秒。 This happens especially in IE as it parses each new element before inserting it.这尤其发生在 IE 中,因为它会在插入之前解析每个新元素。 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(''));

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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