将数百个DOM元素动态插入页面同时保持高性能的最佳方法

时间:2010-09-21 02:09:25

标签: javascript jquery performance

我有一个网络应用,我们将数百个元素插入DOM

基本上,我正在做

 $('#some_element').html('<lots of html here>'); 

反复。在某些情况下,我可能需要$('#some_element').appendTo('more html');

根据以前使用追加或设置插入html文本的经验,元素的innerHTML很慢。

我听说你可以通过首先将元素放在DOM片段中然后将其位置移动到所需元素内来提高性能。

这是关键。你们有什么关于最大化性能的提示或建议吗?我能做些什么来加快速度?

编辑:如评论中所述:该应用涉及各种数据的实时流,因此需要能够不断添加新的DOM元素来表示新数据。 (这也可能导致另一个问题,即DOM元素太多,因此需要太旧的元素)。

3 个答案:

答案 0 :(得分:12)

不要反复执行html()(或使用其原生表亲innerHTML = … 。将您的HTML打包在一个变量中,只执行html()一次(或尽可能少)。 E.g:

var buf = [], i = 0;

buf[i++] = "<p>";               /* or use buf.push(string) */
buf[i++] = "some text";
buf[i++] = "some other text";
buf[i++] = "</p>";

element.innerHTML = buf.join("");

另请参阅Quirksmode entry on innerHTMLW3C DOM vs. innerHTML页。

更新:昨天我发现Steven Levithan关于他的功能replaceHtml的惊人文章When innerHTML isn't Fast Enough,这比仅使用innerHTML更快,因为它在使用 innerHTML之前,使用标准DOM操作删除要替换的DOM节点:

function replaceHtml(el, html) {
    var oldEl = typeof el === "string" ? document.getElementById(el) : el;
    /*@cc_on // Pure innerHTML is slightly faster in IE
        oldEl.innerHTML = html;
        return oldEl;
    @*/
    var newEl = oldEl.cloneNode(false);
    newEl.innerHTML = html;
    oldEl.parentNode.replaceChild(newEl, oldEl);
    /* Since we just removed the old element from the DOM, return a reference
    to the new element, which can be used to restore variable references. */
    return newEl;
};

答案 1 :(得分:1)

澄清马塞尔在答案中所说的话:

DOM操作(使用appendTo,创建Element,TextNode等)的速度比读取/写入innerHTML要慢。

答案 2 :(得分:0)

实时流媒体应更新不附加。如上所述,使用缓冲区。你可以做的另一件事是。

var buffer = [];
setInterval(function(){ $("#div").html(buffer.join(""); buffer = []; }, 1000);

buffer.push("html");
buffer.push("html");

将超时设置为您需要的任何值,它将刷新缓冲区并追加它。

这是您可以使用的功能和间隔。

var buffer = [];
var wait = 1000; /* ms to wait, 1000 = 1 second */
var htmlId = "puthere"; /* Change this to the div ID */

setInterval(function(){
    var tmp = buffer; /* Switch the buffer out quickly so we aren't scrambled 
                         if you addToBuffer in the middle of this */
    buffer = [];
    document.getElementById(htmlId).innerHTML = tmp.join("");
}, wait);

addToBuffer = function(html){
    buffer.push(html);
};