Oct1a

DocumentFragement-关于文档碎片的理解

今天看到一道面试题:如果后端一次性发送10万条数据,前端需要如何优雅的显示?

🙃分析

如果直接进行循环插入肯定会影响整个网页性能,会非常卡顿,每次刷新页面数据需要等待完全渲染,大概花费10秒左右的时间,卡顿非常明显,性能瓶颈是在将html字符串插入到文档中这个过程上,也就是性能瓶颈是在将html字符串插入到文档中这个过程上,增加了DOM树重新渲染时间。

setTimetout

如果是使用延迟分批插入呢,既然一次渲染10万条数据会造成页面加载速度缓慢,那么我们可以不要一次性渲染这么多数据,而是分批次渲染, 比如一次10000条,分10次来完成, 这样或许会对页面的渲染速度有提升。 然而,如果这13次操作在同一个代码执行流程中运行,那似乎不但无法解决糟糕的页面卡顿问题,反而会将代码复杂化。

虚拟列表

这个到时候再另一篇文章单独讲。先挖个坑。

DocumentFragement

DocumentFragment,一个没有父对象的最小文档对象。它被作为一个轻量版的 Document 使用,就像标准的document一样,存储由节点(nodes)组成的文档结构。与document相比,最大的区别是DocumentFragment 不是真实 DOM 树的一部分,它的变化不会触发 DOM 树的重新渲染,且不会导致性能等问题。

这边我们可以简单的将DocumentFragement理解成一个承载器,将大部分工作通过文档碎片来处理,然后输出一个返回值直接给浏览器调用,避免了所有工作都是经过、浏览器处理,从而降低浏览器的性能耗费。

属性

ParentNode.children 只读

返回一个实时(live) HTMLCollection ,包含所有属于 DocumentFragment 的元素类型的子对象。

ParentNode.firstElementChild 只读

返回 DocumentFragment 的第一个 Element 类型的子对象,如果没有则返回 null 。

ParentNode.lastElementChild 只读

返回 DocumentFragment 的最后一个 Element 类型的子对象,如果没有则返回 null 。

ParentNode.childElementCount 只读

返回一个 unsigned long 给出 DocumentFragment 拥有的子项数量。

方法

该接口继承 Node 的全部方法,并实现了 ParentNode 接口中的方法。

DocumentFragment.querySelector()

返回在DocumentFragment中以文档顺序排列的第一个符合指定选择器的Element节点。

DocumentFragment.querySelectorAll()

返回在DocumentFragment中所有的符合指定选择器的Element节点组成的NodeList数组。

DocumentFragment.getElementById()

返回在DocumentFragment中以文档顺序排列的第一个符合指定ID选择器的Element节点。与Document.getElementById()作用相同。

创建案例

//先创建文档碎片

var oFragmeng = document.createDocumentFragment();

for(var i=0;i<10000;i++){

    var op = document.createElement("span");
    var oText = document.createTextNode(i);
    op.appendChild(oText);

    //先附加在文档碎片中
    oFragmeng.appendChild(op);
}

//最后一次性添加到document中
document.body.appendChild(oFragmeng);

本作品采用 知识共享署名-非商业性使用-禁止演绎 4.0 国际许可协议 进行许可。