the-front-end-knowledge-you-may-not-know icon indicating copy to clipboard operation
the-front-end-knowledge-you-may-not-know copied to clipboard

使用 DocumentFragment 提升性能

Open justjavac opened this issue 7 years ago • 3 comments

DocumentFragment 接口表示一个没有父级文件的最小文档对象。

因为 DocumentFragment 不是真实 DOM 树的其中一部分,它的变化不会引起 DOM 树的重新渲染操作(reflow) ,因此不会导致性能问题。

当我们需要修改多个节点时,可以创建一个 DocumentFragment,在此 Node 节点进行添加(append)或被插入(inserted)操作。因为所有的节点会被一次性插入到文档中,而这个操作仅发生一个重渲染的操作,而不是每个节点分别被插入到文档中,因为后者会发生多次重渲染的操作。

documentFragment 被所有主流浏览器支持。

MDN 文档说**似乎IE 6/7/8也支持documentFragment!**

image

随后又写道:

怀疑 caniuse 上给出的数据是错误的,因为起码在 IE8 上这个 document.createDocumentFragment 是可以被调用的。

我刚才查了 can i use 的数据,好像 IE9 以下并不支持。但是 IE9 能够支持已经足够了。


相关文档:


性能测试

appendChild vs. DocumentFragment vs. innerHTML

另一个测试,使用 DocumentFragment 反而会更慢。

image

为什么使用了 DocumentFragment 不但没有变快,反而变慢了呢?

我们看测试代码就知道原因了,为 <select> 添加 option,使用 fragment 的目的是为了防止页面的 reflow 操作,但是给 <select> 添加 option 根本就不会引起页面的 reflow。

justjavac avatar Jul 04 '17 11:07 justjavac

再补一个 test case:https://jsperf.com/document-fragment-test-peluchetti/38

justjavac avatar Jul 04 '17 11:07 justjavac

chrome下在select获得焦点时动态添加option不会显示出来,是没有reflow的原因吗?但是在Firefox 下就可以显示出来

diyijing avatar Jul 05 '17 00:07 diyijing

@imis12 https://jsfiddle.net/Lzo73ozz/

如果没有获得焦点,select 会变长。

在 2 秒之内获得焦点(select 展开)时,select 也会边长,但是 option 不变;当关闭下拉选项,再次打开后,option 变了。

我猜可能是 Chrome 是在触发 dropdown 之后不再监听 option 的变化了。

  • FF 可以
  • Chrome 没有变化
  • Edge 没有变化

justjavac avatar Jul 05 '17 01:07 justjavac