DOM回收

weixin_34041003發表於2018-03-19

DOM回收

DOM回收目的是讓DOM的節點數保持在較低的數值。
概括來說,它的機制是利用那些離開檢視區域的、已經建立的DOM元素,而不是新建DOM元素。
需要承認的一點是DOM節點本身並非耗能大戶,但是也不是一點都不消耗效能,每一個節點都會增加一些額外的記憶體、佈局、樣式和繪製。如果一個站點的DOM節點過多,在低端裝置上會發現明顯的變慢,如果沒有徹底卡死的話。
同樣需要注意的一點是,在一個較大的DOM中每一次重新佈局或重新應用樣式(在節點上增加或刪除樣式所觸發的過程)的系統開銷都會比較昂貴。所以進行DOM回收意味著我們會保持DOM節點在一個比較低的數量上,進而加快上面提到的這些處理過程。

滾動錨點

我們必須要知道在viewport中的最頂部可見元素是什麼。由於這個元素可能只是部分可見的,所以我們也需要儲存從頂部元素到viewport頂部的偏移量。


6456061-8bb51ec07e073a03.png

佈局

每次DOM元素的回收通常情況下都會引發整個列表的重新佈局,這會直接影響我們的效能:無法達成每秒60幀的目標。為避免這一點,我們自己承擔了佈局的重任,使用了絕對定位的元素。這樣我們可以讓所有列表中的元素感覺上還在佔用空間,但其實那裡毛都沒有。由於我們自己在操控佈局,我們便可以快取每個元素消失前的位置,在使用者往回滾動時,我們能立刻從快取中載入正確的元素。

理想情況下,條目應該只被重繪一次,那就是當它們被加到DOM時。而且應該對於列表中其它條目的增加或刪除完全不受影響。這個是可能的,但是隻限於現代瀏覽器。

極致優化

Chrome增加了CSS Containment的支援,這個特性允許開發者告訴瀏覽器某個元素是佈局和繪製的邊界。由於我們這裡採用的是自己來佈局,這是一個很好的可以應用 containment 的機會。當我們增加一個元素到 runaway時,我們知道其它條目不應該被這個重新佈局影響。所以每個條目應該設定一個 contain: layout。我們同樣也不希望影響站點的其它部分,所以列表本身也需要這樣設定。

參考連結

Google infinite-scroller