仲介交易 HTTP://www.aliyun.com/zixun/aggregation/6858.html">SEO診斷淘寶客 站長團購 雲主機 技術大廳
瀑布流的佈局方式展現的內容通常是扁平化、瑣碎的東西。 首先吸引人的應該是圖片,並且圖片是那種參差不齊的,如果瀑布流中文字過多,會給人很雜亂的感覺,所以瀑布流更適合單純的圖片流覽。
前不久公司上線的專案–360圖片搜索的美女秀場頻道,就用到了瀑布流的佈局方式,這種純粹的看美女圖片的頁面用瀑布流還是挺合適的。
以前並未開發過瀑布流佈局的網站,第一個想到的實現方式就是多列浮動,從表面上看這種方式要簡單。
傳統的定位佈局方式
但是,目前主流的瀑布流佈局都是採用定位的方式,對每個儲存格計算定位值,如下圖:
定位的方式實現起來其實也簡單,在視窗 resize 時,也可以方便的對儲存格進行重新計算排序。 但是計算的頻率比較高,如果要做無限的載入資料,以及 resize 時的自我調整排列,那麼性能就是一個必須要重視的問題。
如果沒有任何優化手段,成百上千個儲存格本身就很耗資源,resize 時再全部重新計算一遍,可以想像瀏覽器在這個時候一定很吃力,必然會有瀏覽器假死的情況。
多列浮動的佈局方式
再來看看多列浮動佈局的實現方式,多個儲存格組成一列,無需對單個的儲存格進行定位的計算,然後對整列進行浮動,如下圖:
當然,這種佈局方式在無限載入和 resize 時的自我調整面前,面對著同樣的問題。
自我調整視窗
先說 resize 時的佈局自我調整,雖然浮動佈局的計算沒有定位那麼方便,但要實現自我調整的佈局還是可以的。 比如原來有 4 列,resize 時頁面寬度變小了,只能放 3 列了,儲存格的總數是不變的,資料的順序也是固定的,那麼只有把原來 4 列裡面的儲存格全部清空,按照資料的順序重新計算排序,依次添加到 3 列中。 需要注意的是清空的時候並不是把儲存格的 DOM 元素給刪除掉,而是從 DOM 樹提取出來存放在一個文檔碎片中,這樣就避免了每次都要去創建儲存格的 DOM 元素,節省了創建時的性能開銷,說得通俗點就是離線操作。
無限載入的挑戰
瀏覽器中運行的 WEB 程式並不能像桌面軟體那樣會有足夠多的 CPU 和記憶體去使用。 當網頁中的 DOM 元素的數量呈指數倍的增長,那麼其佔用的記憶體也勢必會成正比的增長,每個 DOM 元素都會有性能開銷,只是通常情況下 DOM 的數量並沒有達到需要注意型性能的那個闕值。
無限載入的瀑布流就必須要注意這種由於 DOM 數量龐大而引發出來的性能問題。 不能抱著僥倖的心理去認為使用者可能滾動不了多長就會跳出。 此次做的瀑布流佈局的專案壓根就沒有內頁,都是浮層直接展示大圖,雖說在一定程度上方便了使用者,但同時也給瀏覽器端很大的性能壓力。 使用者如果不需要跳轉一直停留在瀑布流的清單頁,只要不關閉這個頁面,記憶體就會一直沒有釋放的機會。
雖然頁面可以無限長,但是使用者的顯示器的可視區域是有限的,就好比一個再富有的人,他晚上睡覺時占的面積還是那麼大,床的面積也是有限的。 由於可視區域是有限的,通常會利用這一點對沒載入的 DOM 元素作延遲載入,那麼反過來,能否對已載入的但不在可視區域的 DOM 元素做文章呢?答案是肯定的,人有多大膽,地有多大產嘛。
當頁面向下滾動的時候,瀑布流會創建新的儲存格,老的儲存格就會隨著頁面的向下滾動而處於非可視範圍,既然都不可見了,那麼為了節省性能完全可以把這些老儲存格刪除掉。 當然,也要有技巧性的去刪除。 如果頁面往上滾,滾回去的時候你總不能給使用者看白板,不能這樣坑人。 那麼原來刪除的還得保持原位置加回去。 不悠著點的話,光是這樣一刪一加的兩個動作就夠瀏覽器受的了。 作為 WEB 開發者,要時刻都有瀏覽器是很脆弱的如芒在背的心理。
分組操作
上面說到的有技巧性的刪除就是將那些處於非可視區域的 DOM 元素從 DOM 樹中提取出來,存儲在一個文檔碎片的容器中。 DOM 元素脫離了 DOM 樹也會大大節省性能的開銷,這樣就達到了節省性能的目的。 當然如果僅僅只做到這一步還不太好意思說是技巧。 正是因為這個,我將 HTML 結構再包裹一層,在 ul 外面添加了一個
div ,稱之為一組,其真實結構如下圖所示。
在這裡,組是比列更大的單位,一組可以是可視區域大小的尺寸( 目前組還沒精確到針對不同的解析度 ),一組裡面就是浮動的自我調整螢幕解析度的幾列,每列裡面就是一個個的儲存格。 如上圖,這樣幾列就可以組成一組。 有了組就可以比較方便的將頻繁出入于 DOM 樹中的 DOM 元素的性能開銷平衡的分配到每一組。 可以在頁面滾動向下到指定的位置,只刪除某一組,繼續向下滾再繼續刪除。 每次都刪除處於最頂端的那一組,因為是在非可視區域內,使用者也不會知道你的刪除操作。
頁面的高度是由一個個儲存格給撐起來的,刪除了儲存格後,其高度就會出現變化,由此就會導致頁面的高度也跟著變化。 在刪除前計算出組元素的高度,然後設置其 visibility 為 hidden,讓其在刪除後還保留組元素原有的位置和高度,這樣就不會有高度的變化了。
通過的刪除非可視區域的 DOM 元素的優化方法,可以讓頁面始終保持1-2組儲存格,只要你組內的儲存格的數量能把握好。 這樣就在一定程度上大大的緩解了了頁面中由於 DOM 數量過多而出現的性能開銷的問題。
當視窗 resize 達到重新排序的寬度條件時,還是要將頁面中所有儲存格重新計算排序。 由於非可視區域的儲存格已經不在 DOM 樹中,那麼其計算也沒什麼壓力了。 那些存儲在文檔碎片容器中的儲存格也還是需要計算的,因為如果此時頁面往上滾動時那些離線的儲存格還要重新和使用者見面嘛,只是這個計算並不是在 DOM 樹中而已。