views:

369

answers:

3

Hi.

I'm wondering what is the right way to do dom insertion of complex elements.

Until now, (with jQuery) I used to first build my element and to insert it once finished. I thought that it was the most efficient, since DOM access is costly performance-wise.

But with native js, I read that to avoid memory leaks, each new dom node should be inserted in the dom right after its creation.

Our intranet says :

Dom insertion order Pay attention to DOM insertion order: never append a child element to a root element before the root is itself appended to the DOM.

var root = document.createElement("DIV");
var child = document.createElement("DIV");

// THIS IS WRONG

root.appendChild(child);
document.body.appendChild(root);

// THIS IS CORRECT

document.body.appendChild(root);
root.appendChild(child);

I found online this page which basically explain the same thing (under the Cross-Page Leaks section) : http://www.codeweblog.com/javascript-memory-leak-on-the-collation-of-draft-issues/

Does that mean that there is an opposition between performance and leak-prevention ?

Should new DOM elements be created and manipulated as string before to be inserted ? How are js libraries solving this ? Is DocumentFragments the miracle solution ?

+3  A: 

According to a presentation on the yui website, using innerHTML = 'html here' is the most efficient way to insert html. This is because the browser is optimized to parse HTML very fast, while the DOM, as a standard, is considered flawed, and done improperly in browsers like IE.

So for quickness, innerHTML is the way to go, I do not believe their are memory leaks because its the same engine that is used to parse the html and render the page on load.

Zoidberg
+1  A: 

There is nothing wrong with inserting the child in the parent before inserting it into the document. It is the preferred way (as you suggest, for performance reasons)

The link you specify suggests it results in a leak, but I've never heard of that. They don't do a good job in explaining why it would leak.

If it does leak, it will definitely only leak in IE6 and I suggest you ignore that with it's ever shrinking market share. Preventing leaks in IE6 can be a difficult job and it's not worth it.

Tomas
+1  A: 

The advice you quote is almost certainly inspired by an article written by a member of the IE Team about memory leaks in (unsurprisingly) IE, specifically the section concerning the "DOM Insertion Order Leak Model". Two points are worthy of note:

  1. The article was written in 2005 specifically to address leak issues in IE 6 - IE 7 hadn't even been released at the time;
  2. It is solely concerned with IE; there is no suggestion that any other browser suffers from the same problem.

According to a 2008 post on the IE Team blog (under the subheading "Memory Management Improvements"), IE 7 included improvements to prevent such leaks persisting for the lifetime of the browser window, and IE 8 contained further improvements to hopefully eliminate any need to be concerned about this matter.

So the question you need to ask is: how much of an issue is IE 6 for you? At the end of the day, order of DOM insertion should never have been something to be concerned about, but if (for example) you are working on an intranet app that will be used on IE 6 for some time to come, then you should take note of the points in the 2005 article. If you have the luxury of knowing that IE 6 is scarcely a blip on the radar for your app, then don't worry about any of it.

Oh, and note that appending everything to the parent before appending the parent to the page will provide better performance: rather than having to do a reflow and repaint each time a new child is added, the browser can do one reflow and repaint when everything arrives in one tidy chunk.

NickFitz
I care a lot about IE7 which is my most sensible supported browser. We do not support IE7. So if the leak is not in IE7 I'm fine and I can keep using the approach I have always used. Is IE7 totally free of such leaks or only improved in that respect ?
Olivvv
@Olivvv: if I understand the blog post correctly, there will still be leaks while the user remains on a single page, but they will be resolved when navigating to another page (or, presumably, reloading the existing page). If your interaction model depends on staying on one page and extensively manipulating the DOM for a long period, then you should be aware of the issues described in the article. If however you only do comparatively small amounts of DOM manipulation combined with navigating to other pages, then it shouldn't be an issue.
NickFitz
Yes it is a single-page webapp meant to be loaded only once a day. So it is sensible to even minor memory issues. I guess I'll have to take some time next week to setup a test. I'll post then the results here.
Olivvv
So I have done a simple test page. I have not found any situation where IE7 exhibits a memory leak using that method. Here is my test : http://jsbin.com/ajexe/edit
Olivvv
correct url: jsbin.com/ajexe
Olivvv