摘要:在樹中,文檔片段被其所有的孩子所代替。因?yàn)槲臋n片段存在于內(nèi)存中,并不在樹中,所以將子元素插入到文檔片段時(shí)不會(huì)引起頁(yè)面回流對(duì)元素位置和幾何上的計(jì)算。因此,使用文檔片段通常會(huì)起到優(yōu)化性能的作用。在里說(shuō)過(guò)接口表示文檔的一部分或一段。
DocumentFragments 是DOM節(jié)點(diǎn)。它們不是主DOM樹的一部分。通常的用例是創(chuàng)建文檔片段,將元素附加到文檔片段,然后將文檔片段附加到DOM樹。在DOM樹中,文檔片段被其所有的孩子所代替。因?yàn)槲臋n片段存在于內(nèi)存中,并不在DOM樹中,所以將子元素插入到文檔片段時(shí)不會(huì)引起頁(yè)面回流(reflow)(對(duì)元素位置和幾何上的計(jì)算)。因此,使用文檔片段document fragments 通常會(huì)起到優(yōu)化性能的作用(better performance)。
在W3Cschool里說(shuō)過(guò)
DocumentFragment 接口表示文檔的一部分(或一段)。更確切地說(shuō),它表示一個(gè)或多個(gè)鄰接的 Document 節(jié)點(diǎn)和它們的所有子孫節(jié)點(diǎn)。
DocumentFragment 節(jié)點(diǎn)不屬于文檔樹,繼承的 parentNode 屬性總是 null。
不過(guò)它有一種特殊的行為,該行為使得它非常有用,即當(dāng)請(qǐng)求把一個(gè) DocumentFragment 節(jié)點(diǎn)插入文檔樹時(shí),插入的不是 DocumentFragment 自身,而是它的所有子孫節(jié)點(diǎn)。這使得 DocumentFragment 成了有用的占位符,暫時(shí)存放那些一次插入文檔的節(jié)點(diǎn)。它還有利于實(shí)現(xiàn)文檔的剪切、復(fù)制和粘貼操作,尤其是與 Range 接口一起使用時(shí)更是如此。
可以用 Document.createDocumentFragment() 方法創(chuàng)建新的空 DocumentFragment 節(jié)點(diǎn)。
也可以用 Range.extractContents() 方法 或 Range.cloneContents() 方法 獲取包含現(xiàn)有文檔的片段的 DocumentFragment 節(jié)點(diǎn)。
功能強(qiáng)大,兼容良好,看看下圖
中間插播一張圖片,Document 對(duì)象的方法(來(lái)自w3cschool的手冊(cè))
開(kāi)始之前我們先來(lái)個(gè)例子熱身,告訴大家傳統(tǒng)的插入DOM會(huì)引起什么樣的性能問(wèn)題
var elem = document.createElement("div"), p = document.createElement("p"); p.innerHTML = "elem "; elem.appendChild(p); document.body.appendChild(elem);
正如大家所知,這種代碼非常糟糕(本身沒(méi)有問(wèn)題),只是每次插入數(shù)據(jù)都會(huì)引起頁(yè)面重繪,如果是在循環(huán)之下短時(shí)間內(nèi)多次重繪頁(yè)面簡(jiǎn)直噩夢(mèng)。相關(guān)知識(shí)有個(gè)大神總結(jié)過(guò)的博非常棒頁(yè)面呈現(xiàn)、重繪、回流,不熟悉這方面的人強(qiáng)烈推薦看幾遍.
這里簡(jiǎn)單概括一下:
回流: 因?yàn)樵氐囊?guī)模尺寸,布局,隱藏等改變而需要重新構(gòu)建。
重繪: 一些元素需要更新屬性只是影響元素的外觀,風(fēng)格,而不會(huì)影響布局。
主流瀏覽器都會(huì)有些減少回流、重繪優(yōu)化方面操作.
下面換成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);
看起來(lái)變化不多,無(wú)非就是中間生成一個(gè)文檔片段
var oFragment = document.createDocumentFragment();
生成dom先插入文檔片段
oFragment.append(p);
最后一步前先把文檔片段插入將被插入頁(yè)面的父元素
elem.append(oFragment);
實(shí)際上這些寫法我都不怎么常用,估計(jì)大多數(shù)人都愛(ài)用字符串插入,簡(jiǎn)單快捷,代碼量都喜人
var str = "", document.body.innerHTML = str;str
然后我們實(shí)際測(cè)試一下這三種方法效率到底怎樣?
我們?cè)陧?yè)面放置三個(gè)列表元素,然后分別用三種方法遍歷1000次生成看看;
實(shí)測(cè)數(shù)據(jù)如下:
次數(shù) | Element用時(shí) | Fragment用時(shí) | 字符串用時(shí) |
---|---|---|---|
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 |
可以看到實(shí)際差距大多數(shù)沒(méi)有想象大,有時(shí)候還會(huì)略差,不過(guò)字符串寫法一直穩(wěn)定并且效率最高.
據(jù)說(shuō)createDocumentFragment比直接操作DOM快70%,但是實(shí)踐里沒(méi)看到太明顯的效果,有時(shí)候甚至還不如直接操作,不知道是不是哪里變量因素沒(méi)考慮到,想了挺久,覺(jué)得原因可能是因?yàn)橐晃叶际呛竺嬉淮涡圆迦氲巾?yè)面,實(shí)際測(cè)得都是一次影響DOM的效率,另一個(gè)就是因?yàn)榻Y(jié)構(gòu)簡(jiǎn)單,互相之間不影響布局.基于這種疑點(diǎn)我試試另一個(gè)測(cè)試方法如下
直接生成文本元素然后插入頁(yè)面或者插入DocumentFragment比較,這么看實(shí)際DocumentFragment也就充當(dāng)一個(gè)容器的作用;因?yàn)樽址迦氩荒芤桓哦?去掉異常參考實(shí)測(cè)數(shù)據(jù)如下:
次數(shù) | Element用時(shí) | Fragment用時(shí) |
---|---|---|
1 | 19.1669921875ms | 18.061767578125ms |
2 | 11.82568359375ms | 13.664794921875ms |
3 | 20.093017578125ms | 19.076171875ms |
4 | 15.6650390625ms | 19.4150390625ms |
現(xiàn)在看起來(lái)就比較偏向正常推測(cè)了,
目前也不好說(shuō)什么,畢竟我只在Chrome下測(cè)試,數(shù)據(jù)量足夠但是視圖比較簡(jiǎn)單,
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://specialneedsforspecialkids.com/yun/106248.html
摘要:它的作用是是用來(lái)處理等操作方法的參數(shù)的,統(tǒng)一將其處理為類型節(jié)點(diǎn),并交由函數(shù)處理,即上圖的。作用將返回的插入到的內(nèi)部末尾。方法創(chuàng)建了一虛擬的節(jié)點(diǎn)對(duì)象,節(jié)點(diǎn)對(duì)象包含所有屬性和方法。 showImg(https://segmentfault.com/img/remote/1460000018678706?w=1106&h=535); 前言:這篇我們倒著講 1、有這樣一個(gè)頁(yè)面: app...
摘要:瀏覽者點(diǎn)擊發(fā)送按鈕發(fā)送表單的時(shí)候,隱藏域的信息也被一起發(fā)送到服務(wù)器,用來(lái)發(fā)送,等驗(yàn)證信息時(shí)不會(huì)有瀏覽器不支持,和用戶禁用的煩惱。 盤點(diǎn)一些用得不多卻非常有用的前端知識(shí),靠個(gè)人收集,如有缺漏,請(qǐng)同學(xué)們一起補(bǔ)充 一、DocumentFragment文檔碎片當(dāng)我們用JS的DOM創(chuàng)建很多節(jié)點(diǎn)時(shí),在加入節(jié)點(diǎn)到DOM樹上時(shí),節(jié)點(diǎn)需要一個(gè)個(gè)渲染,這樣節(jié)點(diǎn)數(shù)較多時(shí)就會(huì)影響瀏覽器的渲染效率,這個(gè)時(shí)候我們...
摘要:原文地址在頁(yè)面的生命周期中,一些效果的交互都有可能發(fā)生重排和重繪,這些都會(huì)使我們付出高額的性能代價(jià)。更比而言,重排會(huì)產(chǎn)生比重繪更大的開(kāi)銷。觸發(fā)重繪的操作主要有背景色等屬性的改變我們應(yīng)當(dāng)注意的是重繪不一定導(dǎo)致重排,但重排一定會(huì)導(dǎo)致重繪。 原文地址:http://www.cun-xu.cn/index.ph... 在頁(yè)面的生命周期中,一些效果的交互都有可能發(fā)生重排(Layout)和重繪(P...
摘要:函數(shù)源碼下面是和的源碼,看了之后肯定有話要說(shuō)函數(shù)回調(diào)函數(shù)好吧,我承認(rèn),又是同樣的套路,先交給函數(shù)來(lái)處理,然后函數(shù),我猜這個(gè)時(shí)候函數(shù)肯定是采用方式使綁定當(dāng)前。 歡迎來(lái)我的專欄查看系列文章。 上一章談到了 dom 的幾個(gè)插入操作,雖然插入的方式多種多樣,但只要在懂了原生方法等基礎(chǔ)上,代碼看起來(lái)都不是很復(fù)雜。比較有意思的一個(gè)函數(shù)就是 buildFragment 方法,用來(lái)將 html 字符串...
摘要:它實(shí)際上等于清除當(dāng)前文檔流,重新寫入內(nèi)容方法用于關(guān)閉方法所新建的文檔。如果頁(yè)面已經(jīng)渲染完成關(guān)閉了,再調(diào)用方法,它會(huì)先調(diào)用方法,擦除當(dāng)前文檔所有內(nèi)容,然后再寫入我們的頁(yè)面渲染的時(shí)候就會(huì)去打開(kāi)一個(gè)文檔流,當(dāng)渲染繪制結(jié)束,就關(guān)閉這個(gè)文檔流。 一、DOM簡(jiǎn)介 1、定義: DOM 是 JavaScript 操作網(wǎng)頁(yè)的接口,全稱為文檔對(duì)象模型(Document Object Model)。 2、作...
閱讀 1246·2021-09-01 10:30
閱讀 2117·2021-07-23 10:38
閱讀 895·2019-08-29 15:06
閱讀 3151·2019-08-29 13:53
閱讀 3277·2019-08-26 11:54
閱讀 1822·2019-08-26 11:38
閱讀 2370·2019-08-26 10:29
閱讀 3128·2019-08-23 18:15