(翻译)DOM DocumentFragments

作者:  John Resig 
原文链接:  http://ejohn.org/blog/dom-documentfragments/ 

最近我正在研究    DOM DocumentFragments ,在JavaScript里,我看看用他们能做出什么东西。 粗略的说,一个 DocumentFragment 是一个轻量级的容器,可以持有DOM节点。它是DOM1规范的一部分并且在现代所有浏览器中被广泛支持( IE在版本6中加入了它)。
在研读它们的时候我遇到一个很有趣的点,规范中说:
另外,各个操作--比如给另一个节点插入子节点--可能拿DocumentFragment对象作为参数;这会导致DocumentFragment的所有子节点被移植为这个节点的子列表。
这意味着,如果你有一群节点并且附加他们到一个片段,然后你就可以简单的把这个片段附加给document(这能达到同样的效果,就像你单独的去操作每一个元素)。我立即感觉到这儿可能会存在性能提升。我做了进一步的调查并且注意到DocumentFragments也支持cloneNode方法。这为你进行高效的DOM节点插入操作提供了所有功能。
我做了一个简单的DEMO来测试这个理论(DEMO链接: http://ejohn.org/apps/fragment/)。
让我们来考虑你有一堆节点并要把他们插入到DOM中的情形(在DEMO中是12个节点--8个在最顶层--对着一个乱糟糟的div)。
var elems = [
  document_createElement_x("hr"),
  text( document_createElement_x("b"), "Links:" ),
  document_createTextNode(" "),
  text( document_createElement_x("a"), "Link A" ),
  document_createTextNode(" | "),
  text( document_createElement_x("a"), "Link B" ),
  document_createTextNode(" | "),
  text( document_createElement_x("a"), "Link C" )
];
function text(node, txt){
  node.a( document_createTextNode(txt) );
  return node;
}
一般的附加
如果我们想附加一些借点到document,我们可能会按照常规做法:遍历节点并分别复制他们(然后我们可以继续把他们附加给整个文档)。
var div = document.getElementsByTagName_r("div");
for ( var i = 0; i < div.length; i++ ) {
  for ( var e = 0; e < elems.length; e++ ) {
    div[i].a( elems[e].cloneNode(true) );
  }
}
DocumentFragment 附加
然而,当我们把DocumentFragments带入视野以后我们立即能看到一个不同的结构。开始,我们附加我们的所有的节点到片段本身(由createDocumentFragment方法创建)。
但是当真正往document里 执行插入节点的时候有趣的事情发生了:对所有节点我们只需要调用一次a和cloneNode方法。
var div = document.getElementsByTagName_r("div");
var fragment = document_createDocumentFragment();
for ( var e = 0; e < elems.length; e++ ) {
  fragment.a( elems[e] );
}

for ( var i = 0; i < div.length; i++ ) {
  div[i].a( fragment.cloneNode(true) );
}
设置一些时间戳我们可以看到我们的结果有丰厚的回报:
Browser Normal (ms) Fragment (ms)
Firefox 3.0.1 90 47
Safari 3.1.2 156 44
Opera 9.51 208 95
IE 6 401 140
IE 7 230 61
IE 8b1 120 40
结果表明:在很大程度上被人们忽略的一个方法,对于你的DOM操作能够提供很大的(2-3X)性能提升。

你可能感兴趣的:((翻译)DOM DocumentFragments)