资讯专栏INFORMATION COLUMN

DocumentFragment文档碎片

codercao / 2250人阅读

摘要:在树中,文档片段被其所有的孩子所代替。因为文档片段存在于内存中,并不在树中,所以将子元素插入到文档片段时不会引起页面回流对元素位置和几何上的计算。因此,使用文档片段通常会起到优化性能的作用。在里说过接口表示文档的一部分或一段。

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

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

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

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

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

var elem = document.createElement("div"),
  p = document.createElement("p");

p.innerHTML = "elem ";
elem.appendChild(p);
document.body.appendChild(elem);

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

下面换成DocumentFragments写法看看

var oFragment = document.createDocumentFragment(),
  elem = document.createElement("div"),
  p = document.createElement("p");

p.innerHTML = "frag ";
oFragment.appendChild(p);
elem.appendChild(oFragment);
document.body.appendChild(elem);

看起来变化不多,无非就是中间生成一个文档片段
var oFragment = document.createDocumentFragment();
生成dom先插入文档片段
oFragment.append(p);
最后一步前先把文档片段插入将被插入页面的父元素
elem.append(oFragment);
实际上这些写法我都不怎么常用,估计大多数人都爱用字符串插入,简单快捷,代码量都喜人

var str = "

str

", document.body.innerHTML = str;

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




    
        
        
    

    
        

实测数据如下:

次数 Element用时 Fragment用时 字符串用时
1 14.9560546875ms 18.69482421875ms 3.69921875ms
2 15.73388671875ms 17.1826171875ms 4.7451171875ms
3 15.19482421875ms 16.35205078125ms 3.850830078125ms
4 11.967041015625ms 13.6240234375ms 5.048828125ms

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




    
        
        
    

    
        

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

次数 Element用时 Fragment用时
1 19.1669921875ms 18.061767578125ms
2 11.82568359375ms 13.664794921875ms
3 20.093017578125ms 19.076171875ms
4 15.6650390625ms 19.4150390625ms

现在看起来就比较偏向正常推测了,
目前也不好说什么,毕竟我只在Chrome下测试,数据量足够但是视图比较简单,

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/106248.html

相关文章

  • 当我调用了$().append()后,jQuery内部发生了什么?

    摘要:它的作用是是用来处理等操作方法的参数的,统一将其处理为类型节点,并交由函数处理,即上图的。作用将返回的插入到的内部末尾。方法创建了一虚拟的节点对象,节点对象包含所有属性和方法。 showImg(https://segmentfault.com/img/remote/1460000018678706?w=1106&h=535); 前言:这篇我们倒着讲 1、有这样一个页面: app...

    skinner 评论0 收藏0
  • 盘点前端开发中那些用得少却很实用的功能

    摘要:浏览者点击发送按钮发送表单的时候,隐藏域的信息也被一起发送到服务器,用来发送,等验证信息时不会有浏览器不支持,和用户禁用的烦恼。 盘点一些用得不多却非常有用的前端知识,靠个人收集,如有缺漏,请同学们一起补充 一、DocumentFragment文档碎片当我们用JS的DOM创建很多节点时,在加入节点到DOM树上时,节点需要一个个渲染,这样节点数较多时就会影响浏览器的渲染效率,这个时候我们...

    lcodecorex 评论0 收藏0
  • 重排与重绘

    摘要:原文地址在页面的生命周期中,一些效果的交互都有可能发生重排和重绘,这些都会使我们付出高额的性能代价。更比而言,重排会产生比重绘更大的开销。触发重绘的操作主要有背景色等属性的改变我们应当注意的是重绘不一定导致重排,但重排一定会导致重绘。 原文地址:http://www.cun-xu.cn/index.ph... 在页面的生命周期中,一些效果的交互都有可能发生重排(Layout)和重绘(P...

    warmcheng 评论0 收藏0
  • jQuery 源码系列(十六)html 和 text

    摘要:函数源码下面是和的源码,看了之后肯定有话要说函数回调函数好吧,我承认,又是同样的套路,先交给函数来处理,然后函数,我猜这个时候函数肯定是采用方式使绑定当前。 欢迎来我的专栏查看系列文章。 上一章谈到了 dom 的几个插入操作,虽然插入的方式多种多样,但只要在懂了原生方法等基础上,代码看起来都不是很复杂。比较有意思的一个函数就是 buildFragment 方法,用来将 html 字符串...

    mj 评论0 收藏0
  • DOM操作笔记

    摘要:它实际上等于清除当前文档流,重新写入内容方法用于关闭方法所新建的文档。如果页面已经渲染完成关闭了,再调用方法,它会先调用方法,擦除当前文档所有内容,然后再写入我们的页面渲染的时候就会去打开一个文档流,当渲染绘制结束,就关闭这个文档流。 一、DOM简介 1、定义: DOM 是 JavaScript 操作网页的接口,全称为文档对象模型(Document Object Model)。 2、作...

    newtrek 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<