create/append node vs innerHTML
Does anyone have a good reason to use one over the other? As far as I can t开发者_开发问答ell, create/append node simply prevents you from creating invalid code, while innerHTML allows you to inject multiple nodes at once.
Given that I need to insert several tags, it seems to make sense to use innerHTML. Does anyone have a different take?
This is always a contentious argument, partially because the origin of innerHTML
being somewhat dubious from a standards perspective. I think the QuirksMode article is still relevant, but I'd love to see it updated. Perhaps contact ppk about updating them, though I'm sure he's busy. We could all benefit from performance testing the assumptions we make in web development. In the end claims require hard data to prove, otherwise it's really just talk.
Anyway, I did some searching and found some interesting articles relevant to this discussion. I don't remember hearing of DocumentFragments before, they're real interesting.
- DOM DocumentFragments
- jQuery Performance Rules
- Improve your jQuery - 25 excellent tips
- Speed test: innerHTML versus DOM manipulation ... a test that actually tests the speed, worth it for anyone who wants to collect some current data on browsers
Given that I need to insert several tags, it seems to make sense to use innerHTML.
Only ‘several’? Then speed is not an issue. It's when you're creating a hundred you have to think about what you're doing. It's not really the creating that's the problem, it's the child node list manipulation that gets slower and slower as you add each extra element.
As for appending, you don't really have any choice. You can't set the innerHTML without losing the existing content, so unless you're happy with serialising and re-parsing that (which wipes out any non-serialisable data like form contents, JavaScript properties/references and event handlers) you end up setting the innerHTML of another element and moving each child over one by one. This is what many frameworks do and it typically ends up even slower than manual create-and-appendChild.
Depending on your situation (specifically: how many child nodes are already in the target element, and how many are you going to add?) it can be faster to break down the operation into smaller manipulations on a DocumentFragment, whose children can be appended to an element's children all in one go instead of one-by-one. This is much faster. Unfortunately, it is not possible to set innerHTML
on a DocumentFragment.
There may also be faster hacks using Range objects to move a load of HTML at once, but unfortunately Ranges are highly cross-browser variable. It seems to me, though, that someone ought to be able to build a fast append-html out of IE's range.pasteHTML and W3's range.extractContents. Anyone up for it?
As far as I can tell, create/append node simply prevents you from creating invalid code
Potentially invalid markup doesn't just mean your application breaks in some browsers. When you're blindly splicing together HTML without escaping like an idiot:
element.innerHTML= '<a href="'+url+'">'+title+'</a>';
then you have a client-side cross-site-scripting security hole that is just as bad as a server-side one.
You can, of course, compromise, by creating the elements and setting their contents in separate steps. For example:
element.innerHTML= '<table>'+'<tr><td>X</td><td><a href="#">go</a></td></tr>'.repeated(urls.length)+'</table>';
for (var i= 0; i<urls.length; i++) {
var row= element.firstChild.rows[i];
row.cells[0].firstChild.data= urls[i];
row.cells[1].firstChild.href= urls[i];
}
(string.repeated is not standard JavaScript, but its use here is obvious.)
DOM MANIPULATION IS WAY FASTER IF YOU USE THIS TRICK!.
This is slow:
var target = document.getElementById('whatever');
for (a = 0; a<10000; a++) {
var newnode = document.createElement('div');
newnode.textContent = a;
target.appendChild(newnode) }
This is fast:
var target = document.createElement('span')
for (a = 0; a<10000; a++) {
var newnode = document.createElement('div');
newnode.textContent = a;
target.appendChild(newnode) }
document.getElementById('whatever').appendChild(target);
The first example appends the newly created node to a node that already is contained inside the body so a refresh is made each time.
The second example appends newly created nodes to a "buffer" node that is not inside the scope of the body, so no refresh is made until you place the buffer node inside the scope of the body. Try it yourself!.
If performance matters, it's good to know that the innerHTML
is relatively fast, especially in MSIE: http://www.quirksmode.org/dom/innerhtml.html
It has however the bad image of originally being a "Microsoft proprietary" property and/or not really "OO".
I believe that on certain platforms, you'll receive a performance boost using the DOM functions instead of innerHTML, as no expensive HTML parsing needs to be done.
It depends on what your goal is.
Using DOM methods to insert html into a document will allow you to further manipulate those elements before / after inserting them.
The difference is creating nodes via the DOM is standardized, but innerHTML is merely a de-facto standard. I've read that innerHTML can be faster.
An even better alternative is to use a library like jQuery for your DOM manipulation. It'll take care of most cross-browser incompatibilities and be more readable than using the DOM methods.
精彩评论