DocumentFragment文档碎片

原创 Lin_Grady 教程 javascript/jQuery 205阅读 2017-06-15 20:45:56 举报

DocumentFragments 是DOM节点。它们不是主DOM树的一部分。通常的用例是创建文档片段,将元素附加到文档片段,然后将文档片段附加到DOM树。在DOM树中,文档片段被其所有的孩子所代替。因为文档片段存在于内存中,并不在DOM树中,所以将子元素插入到文档片段时不会引起页面回流(reflow)(对元素位置和几何上的计算)。因此,使用文档片段document fragments 通常会起到优化性能的作用(better performance)。

在W3Cschool里说过
[quote]DocumentFragment 接口表示文档的一部分(或一段)。更确切地说,它表示一个或多个邻接的 Document 节点和它们的所有子孙节点。
DocumentFragment 节点不属于文档树,继承的 parentNode 属性总是 null。
不过它有一种特殊的行为,该行为使得它非常有用,即当请求把一个 DocumentFragment 节点插入文档树时,插入的不是 DocumentFragment 自身,而是它的所有子孙节点。这使得 DocumentFragment 成了有用的占位符,暂时存放那些一次插入文档的节点。它还有利于实现文档的剪切、复制和粘贴操作,尤其是与 Range 接口一起使用时更是如此。
可以用 Document.createDocumentFragment() 方法创建新的空 DocumentFragment 节点。
也可以用 Range.extractContents() 方法 或 Range.cloneContents() 方法 获取包含现有文档的片段的 DocumentFragment 节点。[/quote]

功能强大,兼容良好,看看下图

DocumentFragment文档碎片

中间插播一张图片,Document 对象的方法(来自w3cschool的手册)

DocumentFragment文档碎片

开始之前我们先来个例子热身,告诉大家传统的插入DOM会引起什么样的性能问题
javascript 代码

正如大家所知,这种代码非常糟糕(本身没有问题),只是每次插入数据都会引起页面重绘,如果是在循环之下短时间内多次重绘页面简直噩梦。相关知识有个大神总结过的博非常棒页面呈现、重绘、回流,不熟悉这方面的人强烈推荐看几遍.
这里简单概括一下:
回流: 因为元素的规模尺寸,布局,隐藏等改变而需要重新构建。
重绘: 一些元素需要更新属性只是影响元素的外观,风格,而不会影响布局。
主流浏览器都会有些减少回流、重绘优化方面操作.

下面换成DocumentFragments写法看看
javascript 代码

看起来变化不多,无非就是中间生成一个文档片段
var oFragment = document.createDocumentFragment();
生成dom先插入文档片段
oFragment.append(p);
最后一步前先把文档片段插入将被插入页面的父元素
elem.append(oFragment);

实际上这些写法我都不怎么常用,估计大多数人都爱用字符串插入,简单快捷,代码量都喜人
html 代码

然后我们实际测试一下这三种方法效率到底怎样?
我们在页面放置三个列表元素,然后分别用三种方法遍历1000次生成看看;
html 代码

实测数据如下:
Element用时 : 5.807861328125ms
Fragment用时: 6.42431640625ms
字符串用时 : 1.85009765625ms

Element用时 : 6.93994140625ms
Fragment用时: 6.4658203125ms
字符串用时 : 1.856689453125ms

Element用时 : 6.93994140625ms
Fragment用时: 6.4658203125ms
字符串用时 : 1.856689453125ms

Element用时 : 10.60791015625ms
Fragment用时: 6.651123046875ms
字符串用时 : 1.4521484375ms

Element用时 : 4.35302734375ms
Fragment用时: 5.07373046875ms
字符串用时 : 2.8779296875ms

可以看到实际差距大多数没有想象大,有时候还会略差,不过字符串写法一直稳定并且效率最高.
据说createDocumentFragment比直接操作DOM快70%,但是实践里没看到太明显的效果,有时候甚至还不如直接操作,不知道是不是哪里变量因素没考虑到,想了挺久,觉得原因可能是因为一我都是后面一次性插入到页面,实际测得都是一次影响DOM的效率,另一个就是因为结构简单,互相之间不影响布局.基于这种疑点我试试另一个测试方法如下
html 代码

直接生成文本元素然后插入页面或者插入DocumentFragment比较,这么看实际DocumentFragment也就充当一个容器的作用;因为字符串插入不能一概而论,去掉异常参考实测数据如下:
Element用时 : 13.2470703125ms
Fragment用时: 5.90478515625ms

Element用时 : 13.875ms
Fragment用时: 5.782958984375ms

Element用时 : 5.031005859375ms
Fragment用时: 5.5439453125ms

Element用时 : 10.3740234375ms
Fragment用时: 10.48681640625ms

Element用时 : 10.044677734375ms
Fragment用时: 7.98486328125ms
现在看起来就比较偏向正常推测了,

评论 ( 0 )
最新评论
暂无评论

赶紧努力消灭 0 回复