Poor IE performance using documentFragment

To test the DOM manipulation compared to innerHTML, I developed this little testing method using the documentFragment ( ) web page to add 10,000 href elements to the div element. Performance is suitable for Chrome or Firefox, but in IE (10, 9, 8) it is very bad, it takes about 10-12 seconds . Can someone explain this difference and / or develop a performance solution for IE?

Here jsfiddle demonstrates it.

Method:

 function useFragment(){ var frag = document.createDocumentFragment(), i = 10000, rval = document.createElement('span'); frag.appendChild(rval); do { var optText = 'option '+i ,ref = document.createElement('a') ,zebra = i%2 ? 'zebra' : '' ,islist = true ,isSel = i === 5 ; rval.insertBefore(ref,rval.firstChild); ref.appendChild(document.createTextNode(optText)); ref.id = 'opt' + i; ref.className = zebra + (islist && isSel ? ' scrollSelect' : ''); ref.href = '#' + i; ref.title = optText; } while (i-->0); return rval; } 
+3
source share
2 answers

I think I found it: it seems that although documentFragment should be an β€œoff line” element (an element that is not part of the Live DOM), IE does not consider it as such. The way to make the fragment really disconnect from the string is to add some element to it, set its display property to none and add the rest of the elements to this element. Once you're done, remove the display:none property, and documentFragment can be added to the DOM.

It is still three times slower (on my PC, it still takes about 1-1.5 seconds, and about 2-300 ms in Chrome / Firefox for 10,000 elements). Thus, for IE (even version 10), using innerHTML to add a bunch of elements to the DOM is a faster way. I would say that IE remains a developer nightmare.

+8
source

As far as I know, the best advantage is adding a large number of isolated elements to the fragment and adding this element before all children and attributes are fixed (post append). If I understand your code (I have to decode it lazily), there is one gap that you add to the fragment. This is not the meaning of documentFragment. By the way: you should not declare your vars in a loop.

 var node=document.getElementById("whatever") ,frag=document.createDocumentFragment() ,i=0,len=50,a={},img={}; for(i;i<len;i++){ a=document.createElement("a"); img=document.createElement("img"); a.href="image"+i; img.className=J[i][1]; img.src="image/img"+i+".png"; img.alt="image:"+i; a.appendChild(img); frag.appendChild(a); } node.appendChild(frag); 

Thus, IE8 Opera12 takes the same time as innerHTML. The real benefit is chrome. FF is incredibly fast with innerHTML. Tested on an old XP machine.

Another thought is to create a node that is not associated with the DOM with all the child elements and attributes, clone it several times, manipulate it and add it to documentFragment.

 var frag=document.createDocumentFragment() ,toFill=document.getElementById("imageCollection") ,i=0,a={},img={} ,dummy=document.createElement("a") ; dummy.innerHTML="<img src='img/image_' />"; for(i;i<50;i++){ a=dummy.cloneNode(true); img=a.getElementsByTagName("img")[0]; a.href="description_"+i+".html"; img.src+=i+".png"; frag.appendChild(a); } toFill.appendChild(frag); 

This is useful if you do not need to do a lot of manipulation of the cloned node.

0
source

All Articles