views:

90

answers:

3

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).

+2  A: 

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;

buf[i++] = "<p>";
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.

Marcel Korpel
The app involves a real-time stream of various data, so it needs to be able to constantly add new DOM elements.
rksprst
@rksprst: but if you do this in one run, you won't notice, as script execution blocks rerendering. “[F]irst putting the elements in a DOM fragment and then moving its location to inside the element” is actually what I'm showing. There's no faster way, at least as far as I know.
Marcel Korpel
+1  A: 

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);
};
Josh K
A: 

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.

Sam Day