摘要:在樹中,文檔片段被其所有的孩子所代替。因為文檔片段存在于內存中,并不在樹中,所以將子元素插入到文檔片段時不會引起頁面回流對元素位置和幾何上的計算。因此,使用文檔片段通常會起到優化性能的作用。在里說過接口表示文檔的一部分或一段。
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 = "", document.body.innerHTML = str;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下測試,數據量足夠但是視圖比較簡單,
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://m.specialneedsforspecialkids.com/yun/106248.html
摘要:它的作用是是用來處理等操作方法的參數的,統一將其處理為類型節點,并交由函數處理,即上圖的。作用將返回的插入到的內部末尾。方法創建了一虛擬的節點對象,節點對象包含所有屬性和方法。 showImg(https://segmentfault.com/img/remote/1460000018678706?w=1106&h=535); 前言:這篇我們倒著講 1、有這樣一個頁面: app...
摘要:瀏覽者點擊發送按鈕發送表單的時候,隱藏域的信息也被一起發送到服務器,用來發送,等驗證信息時不會有瀏覽器不支持,和用戶禁用的煩惱。 盤點一些用得不多卻非常有用的前端知識,靠個人收集,如有缺漏,請同學們一起補充 一、DocumentFragment文檔碎片當我們用JS的DOM創建很多節點時,在加入節點到DOM樹上時,節點需要一個個渲染,這樣節點數較多時就會影響瀏覽器的渲染效率,這個時候我們...
摘要:函數源碼下面是和的源碼,看了之后肯定有話要說函數回調函數好吧,我承認,又是同樣的套路,先交給函數來處理,然后函數,我猜這個時候函數肯定是采用方式使綁定當前。 歡迎來我的專欄查看系列文章。 上一章談到了 dom 的幾個插入操作,雖然插入的方式多種多樣,但只要在懂了原生方法等基礎上,代碼看起來都不是很復雜。比較有意思的一個函數就是 buildFragment 方法,用來將 html 字符串...
閱讀 1253·2021-09-01 10:30
閱讀 2130·2021-07-23 10:38
閱讀 904·2019-08-29 15:06
閱讀 3159·2019-08-29 13:53
閱讀 3283·2019-08-26 11:54
閱讀 1836·2019-08-26 11:38
閱讀 2377·2019-08-26 10:29
閱讀 3132·2019-08-23 18:15