問題
在某些情況下,有些頁面需要顯示大量的資料 ,但因為資料量大太,渲染及執行過程中,瞬間造成瀏覽器卡頓或不回應。
主因
從上面的例子,經過反覆調查研究得知
- 頁面的卡頓是由於同時渲染大量DOM所引起的。
- 過多的 DOM 同時出現在一個頁面,電腦或手機效能不好時,也會卡頓。
- 因為我們前端框架採用 Vue ,渲染越多的元件,則會產生越多的 Virtual DOM,當資料變動時,也可能觸發元件的重新渲染。
解決方法
1.分時渲染 - 頁面的卡頓是由於同時渲染大量DOM所引起的,所以我們透過 setTimeout 將渲染過程分批進行渲染。
- 缺點使用 setTimeout 頁面加載的時間已經非常快了,但每次刷新時可以很快的看到第一屏的所有數據,但是當我們快速滾動頁面的時候,會發現頁面出現閃屏或白屏的現象。
2.捲動式渲染(Lazylading Rendering) - 依據每次捲動軸捲動去多渲染幾筆資料。
- Lazy loading 不等於 虛擬列表/虛擬捲軸,虛擬列表每次只會渲染可視範圍的筆數。
- 當資料筆數過多時,會渲染過多的 DOM,也會造成瀏覽器卡頓。
- 明明是一千筆資料,因為捲軸往下捲才長出捲軸,捲軸 bar 比例顯示比例不正常,也不好捲動
。
3.分段渲染 - 依據資料筆數及高度長出,虛擬捲軸Bar,依可視範圍做渲染,超出可視範圍的就不渲染額外的 DOM 了
- Clusterize.js 套件
- 虛擬滾動(Vue-virtual-scroller) 套件
- Vue 虛擬列表元件 範例連結
- 自己做分頁元件渲染
結論
依據效能及使用者體驗,依情境最後推薦的做法是分段渲染。
補充
- 額外優化渲染的議題
- 縮減物件的大小,去除不需要的屬性 ( Limit unnecessary data passing )
- 過濾掉不需要的資料
- Render Once - 假設Component其中一個內容不會變更資料,可以用v-once指令,只針對那個內容僅渲染一次。