页面优化,DocumentFragment对象详解
一、前言
最近项目不是很忙,所以去看了下之前总想整理的重汇和回流的相关资料,关于回流优化,提到了DocumentFragment的使用,这个对象在3年前我记得是有看过的,但是一直没深入了解过,所以这里做个整理。后面会把重汇,回流也做个整理,不鸽。
二、DocumentFragment对象是什么?
MDN解释:
DocumentFragment 表示一个没有父级文件的最小文档对象。它被当做一个轻量版的 Document 使用,用于存储已排好版的或尚未打理好格式的XML片段。最大的区别是因为DocumentFragment不是真实DOM树的一部分,它的变化不会引起DOM树的重新渲染的操作(reflow) ,且不会导致性能等问题。---MDN
W3C解释:
DocumentFragment 接口表示文档的一部分(或一段)。更确切地说,它表示一个或多个邻接的 Document 节点和它们的所有子孙节点。 DocumentFragment 节点不属于文档树,继承的 parentNode 属性总是 null。 不过它有一种特殊的行为,该行为使得它非常有用,即当请求把一个 DocumentFragment 节点插入文档树时,插入的不是 DocumentFragment 自身,而是它的所有子孙节点。这使得 DocumentFragment 成了有用的占位符,暂时存放那些一次插入文档的节点。它还有利于实现文档的剪切、复制和粘贴操作,尤其是与 Range 接口一起使用时更是如此。 可以用 Document.createDocumentFragment() 方法创建新的空 DocumentFragment 节点。---W3C
怎么去理解呢?我们结合上面两解释可以得知,DocumentFragment 节点不属于DOM树,因此它的变化不会引起DOM树的变化;
我们知道,DOM树的操作会引起回流,那我们可以将DocumentFragment作为一个暂时的DOM节点存储器,当我们在DocumentFragment 修改完成时,我们就可以将存储DOM节点的DocumentFragment一次性加入DOM树,从而减少回流次数,达到性能优化的目的。
三、DocumentFragment对象怎么用?
我们可以使用document.createDocumentFragment()创建一个DocumentFragment,每个新建的DocumentFragment都会继承所有node方法。且DocumentFragment拥有nodeValue,nodeName,nodeType属性。
let fragment = document.createDocumentFragment();
console.log(fragment.nodeValue); //null
console.log(fragment.nodeName); //#document-fragment
console.log(fragment.nodeType); //
使用DocumentFragment能解决直接操作DOM引发大量回流的问题,比如我们要给ul添加五个li节点,区别就像这样:
直接操作DOM,回流五次:

使用DocumentFragment一次性添加,回流一次:

假设我们给ul加入五万个li,分别对比下渲染完成时间:
html:
<body>
<ul id="list"></ul>
<ul id="list1"></ul>
</body> js:
//使用documentFragment添加节点
console.time("time")
let list = document.querySelector("#list"),
fragment = document.createDocumentFragment(),
n = 50000;
while(n--){
fragment.appendChild(document.createElement("li"));
};
list.appendChild(fragment);
console.timeEnd("time") //直接操作DOM添加节点
console.time("time1")
let list1 = document.querySelector("#list1"),
i = 50000;
while(i--){
list1.appendChild(document.createElement("li"))
};
console.timeEnd("time1")
多刷新几次对比两者的耗时,time是使用了DocumentFragment的耗时,time1是直接添加DOM的耗时

很明显,time比time1耗时要短很多。
再刷新几次试试

很明显,多次刷新反而还会出现使用DocumentFragment耗时更久的情况,性能更差?打脸了。暂时无法解释,希望有大佬能说说。
不过读到这,也明白了DocumentFragment是个什么东西,怎么使用它,那么本文就到这里结束了。

参考资料
深入理解DOM节点类型第四篇——文档片段节点DocumentFragment
页面优化,DocumentFragment对象详解的更多相关文章
- Window 对象详解 转自 http://blog.csdn.net/jcx5083761/article/details/41243697
详解HTML中的window对象和document对象 标签: HTMLwindowdocument 2014-11-18 11:03 5884人阅读 评论(0) 收藏 举报 分类: HTML& ...
- mvc-servlet---ServletConfig与ServletContext对象详解(转载)
ServletConfig与ServletContext对象详解 一.ServletConfig对象 在Servlet的配置文件中,可以使用一个或多个<init-param>标签为s ...
- JavaWeb学习----JSP内置对象详解
[声明] 欢迎转载,但请保留文章原始出处→_→ 生命壹号:http://www.cnblogs.com/smyhvae/ 文章来源:http://www.cnblogs.com/smyhvae/p/4 ...
- django中request对象详解(转载)
django中的request对象详解 Request 我们知道当URLconf文件匹配到用户输入的路径后,会调用对应的view函数,并将 HttpRequest对象 作为第一个参数传入该函数. ...
- dom对象详解--document对象(一)
document对象 Document对象代表整个html文档,可用来访问页面中的所有元素,是最复杂的一个dom对象,可以说是学习好dom编程的关键所在. Document对象是window对象的一 ...
- js对象详解(JavaScript对象深度剖析,深度理解js对象)
js对象详解(JavaScript对象深度剖析,深度理解js对象) 这算是酝酿很久的一篇文章了. JavaScript作为一个基于对象(没有类的概念)的语言,从入门到精通到放弃一直会被对象这个问题围绕 ...
- Angular.js中处理页面闪烁的方法详解
Angular.js中处理页面闪烁的方法详解 前言 大家在使用{{}}绑定数据的时候,页面加载会出现满屏尽是{{xxx}}的情况.数据还没响应,但页面已经渲染了.这是因为浏览器和angularjs渲染 ...
- Vue实例初始化的选项配置对象详解
Vue实例初始化的选项配置对象详解 1. Vue实例的的data对象 介绍 Vue的实例的数据对象data 我们已经用了很多了,数据绑定离不开data里面的数据.也是Vue的核心属性. 它是Vue绑定 ...
- jQuery的deferred对象详解
jQuery的deferred对象详解请猛击下面的链接 http://www.ruanyifeng.com/blog/2011/08/a_detailed_explanation_of_jquery_ ...
随机推荐
- cf 1142 C
忽然觉得这个题很有必要写题解. 移项 y-x^2 = bx+c 那么其实就是找有多少条直线上方没有点 所以就是一个上凸壳有多少条直线/点. 绝妙啊!!!! 太妙了啊!!!! 神乎其技卧槽!!! (我是 ...
- Java语法细节 - 可见性
目录 JAVA访问和修饰符的关系一览表 JAVA访问和修饰符的关系一览表 Modifier Class Package Subclass World public Y Y Y Y protected ...
- NFS 系统搭建 - 成功
NFS是Network File System的缩写,即文件系统.客户端通过挂载的方式将NFS服务器端共享的数据目录挂载到本地目录下. 工作流程 1.由程序在NFS客户端发起存取文件的请求,客户端本地 ...
- pymongo的操作
实例化和插入 from pymongo import MongoClient class TestMongo: def __init__(self): client = MongoClient(hos ...
- 基于Jmeter的thrift-RPC接口测试
根据需求,产品部分功能采用thrift-RPC协议进行接口的增.删.改.查,前期采用Junit对其进行测试,为了提高RPC接口测试的简洁化和后期的性能测试需求,打算通过Jmeter的java类测试实现 ...
- AI-2.梯度下降算法
上节定义了神经网络中几个重要的常见的函数,最后提到的损失函数的目的就是求得一组合适的w.b 先看下损失函数的曲线图,如下 即目的就是求得最低点对应的一组w.b,而本节要讲的梯度下降算法就是会一步一步地 ...
- Oracle 查询表空间使用情况
select * from (Select a.tablespace_name, to_char(a.bytes / 1024 / 1024, '99,999.999 ...
- JVM之垃圾回收
1.哪些内存需要回收?判断对象已死的方法(存活判定算法) 1.引用计数算法:难以解决对象之间相互循环引用的问题,不使用. 2.可达性分析算法:通过一系列“GC Root”对象作为起始点向下搜索,所走过 ...
- FCC(ES6写法) No repeats please
把一个字符串中的字符重新排列生成新的字符串,返回新生成的字符串里没有连续重复字符的字符串个数.连续重复只以单个字符为准. 例如, aab 应该返回 2 因为它总共有6中排列 (aab, aab, ab ...
- Eclipse格式化整个项目
Eclipse有一个非常好的功能,就是把源代码进行美化(或者是标准化),在打开的Java源代码中,Ctrl+Shift+F就可做到. 但是,如果你想把整个项目中的源代码都美化一下呢?这里有一个简单的办 ...