使用documentFragment的IE性能不佳

时间:2012-12-29 09:29:10

标签: javascript internet-explorer dom-manipulation

为了测试DOM操作与innerHTML,我使用documentFragmentweb page)来设计这个小测试方法,将10000 href个元素附加到div元素。 Chrome或Firefox的性能还可以,但在IE(10,9,8)中它的表现非常糟糕,需要 10-12秒 。任何人都可以解释这种差异和/或详细说明提高IE性能的解决方案吗?

这是展示它的jsfiddle

方法:

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

2 个答案:

答案 0 :(得分:8)

认为我已经找到了它:它看起来像,虽然documentFragment应该是一个'离线'元素(一个不属于实时DOM的元素) IE不会对它进行处理就这样。强制片段真正离线的方法是向其附加一些元素,将其display属性设置为none并将其余元素追加到该元素。完成后,删除display:none属性,documentFragment可以附加到DOM。

它仍然慢三倍(在我的电脑上它仍然需要大约1-1.5秒,而在Chrome / Firefox中大约需要2-300毫秒才能获得10000个元素)。因此,对于IE(甚至是版本10),使用innerHTML向DOM添加一堆元素是更快的方法。我会说,IE仍然是开发者的噩梦。

答案 1 :(得分:0)

就我的经验而言,最好的好处是在片段中附加了很多孤立的元素,并且在所有子元素和属性都被修复之前附加该元素(post append)。 如果我理解你的代码(我真的懒得解码它),你可以在片段中追加一个范围。这不是documentFragment的意义。顺便说一下:你不应该循环声明你的变量。

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

这样IE8 Opera12的时间与innerHTML完全相同。真正的好处是铬。使用innerHTML,FF令人难以置信。在旧的XP机器上测试过。

另一件需要考虑的事情是创建一个没有连接到DOM的节点,包含所有子节点和属性,多次克隆它,操作它并将其附加到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);   

如果您不需要对克隆节点进行大量操作,这将非常有用。