【问题标题】:Bad performance IE using documentFragment使用 documentFragment 的 IE 性能不佳
【发布时间】:2012-12-14 08:37:49
【问题描述】:

为了测试 DOM 操作与 innerHTML,我使用documentFragment (web 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;
}

【问题讨论】:

  • 我以前从未听说过文档碎片...
  • 您好 Jan,添加了关于该主题的 Resig 文章的链接。
  • 我认为你测量时间的方式是有缺陷的。例如,您在片段计时的计时区域内定义 useInnerHtmlBttn.onclick 处理程序。
  • 可能是这样(jsfiddle现在调整了),但基本的一点是IE使用这种方法非常非常慢。除了 IE 怪物总是较慢并且总是需要 tweeking 才能使事情正常工作这一事实之外,我就是不知道为什么。
  • 您的测量结果与您链接的文章中的观察结果不一致。

标签: javascript internet-explorer dom-manipulation


【解决方案1】:

认为我找到了它:看起来,虽然 documentFragment 应该是“离线”元素(不属于活动 DOM 的元素)IE 不会这样对待它。强制片段真正脱机的方法是向其附加一些元素,将其display 属性设置为none 并将其余元素附加到该元素。完成后,删除display:none 属性,documentFragment 可以附加到 DOM。

它仍然慢了三倍(在我的 PC 上它仍然需要大约 1-1.5 秒,而在 Chrome/Firefox 中对于 10000 个元素大约需要 2-300 毫秒)。所以,对于 IE(甚至是 10 版)来说,使用innerHTML 向 DOM 添加一堆元素是更快的方法。我想说,IE 仍然是开发人员的噩梦。

【讨论】:

    【解决方案2】:

    就我的经验而言,最大的好处是将许多孤立的元素附加到片段中,并且不要在所有子元素和属性都固定(后附加)之前附加该元素。 如果我理解你的代码(我真的懒得解码它),你会在片段中附加一个跨度。这不是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 差不多。真正的好处是铬。 FF 使用 innerHTML 的速度令人难以置信。在旧的 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);   
    

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2015-11-15
      • 2011-12-13
      • 1970-01-01
      • 2013-06-01
      • 2012-01-14
      • 2016-06-01
      • 1970-01-01
      相关资源
      最近更新 更多