最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Best way to insert hundreds of DOM elements into the page dynamically while keeping performance high - Stack Overfl

programmeradmin3浏览0评论

I have a web app where we would be inserting hundreds of elements into the DOM

Essentially, I'm doing

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

repeatedly. In some cases I might need to do $('#some_element').appendTo('more html');

From previous experience inserting html text using the append or setting the innerHTML of an element is slow.

I've heard that you can increase performance by first putting the elements in a DOM fragment and then moving its location to inside the element you want.

The performance of this is key. Do you guys have any tips or suggestions on maximizing the performance? Any hacks I can do to make this fast?

Edit: as mentioned in a comment: The app involves a real-time stream of various data, so it needs to be able to constantly add new DOM elements to represent the new data. (This might also lead to another problem of having too many DOM elements, so would need to elements that are too old).

I have a web app where we would be inserting hundreds of elements into the DOM

Essentially, I'm doing

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

repeatedly. In some cases I might need to do $('#some_element').appendTo('more html');

From previous experience inserting html text using the append or setting the innerHTML of an element is slow.

I've heard that you can increase performance by first putting the elements in a DOM fragment and then moving its location to inside the element you want.

The performance of this is key. Do you guys have any tips or suggestions on maximizing the performance? Any hacks I can do to make this fast?

Edit: as mentioned in a comment: The app involves a real-time stream of various data, so it needs to be able to constantly add new DOM elements to represent the new data. (This might also lead to another problem of having too many DOM elements, so would need to elements that are too old).

Share Improve this question edited Sep 21, 2010 at 2:18 Marcel Korpel 21.8k6 gold badges62 silver badges80 bronze badges asked Sep 21, 2010 at 2:09 rksprstrksprst 6,63119 gold badges57 silver badges81 bronze badges 3
  • 3 Given the requirements, your current approach seems reasonable. Does it feel slow currently? – Sean Hogan Commented Sep 21, 2010 at 2:36
  • Yea, there's a tiny lag as the browser renders the new html. So the browser feels frozen for 300ms to 600ms. But as there's more data I don't want that increase, which is what I'm worried about. – rksprst Commented Sep 21, 2010 at 3:30
  • 1 Can you provide a sample web-page? – Sean Hogan Commented Sep 21, 2010 at 7:48
Add a comment  | 

3 Answers 3

Reset to default 13

Just don't do html() (or use its native cousin innerHTML = …) repeatedly. Pack your HTML in one variable and do html() only once (or as few times as possible). 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("");

Also see the Quirksmode entry on innerHTML and the W3C DOM vs. innerHTML page.

Update: Yesterday I found the amazing article When innerHTML isn't Fast Enough by Steven Levithan about his function replaceHtml, which is even faster than using just innerHTML, because it removes the DOM nodes that are to be replaced using standard DOM manipulation before innerHTML is used:

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;
};

To clarify what Marcel said in his answer:

DOM manipulation (using appendTo, creating Element's, TextNode's, etc) is orders of magnitudes slower than just read/writing innerHTML.

Real time streaming should update not append. As mentioned, use a buffer. Another thing you could do is.

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

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

Set the timeout to whatever you need and it will flush the buffer and append it.

Here is a function and interval you can use.

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);
};

与本文相关的文章

发布评论

评论列表(0)

  1. 暂无评论