1. 程式人生 > >table元件的固定列和表頭 優化

table元件的固定列和表頭 優化

對於需要固定表頭和表列的table,往往資料量都比較大。我們可以對現有的實現方式做更進一步的優化嘗試。

使用tranfrom來代替設定scrollLeft

考慮瀏覽器重排和重繪,一般來說,scrollLeft會引起一次重排,而transfrom僅僅是一次重繪,同時我們可以使用transform3D使用GPU來加速瀏覽器的渲染。那麼,是不是可以考慮在scroll事件中,使用transform來代替scrollLeft的設定呢?
React 實現一個漂亮的 Table | HYPERS 前端團隊部落格這篇文章中,有提及到實現一個優化的table元件使用下面兩點來優化onScroll 觸發的頻率和渲染的速度跟不上造成的抖動問題,他的解決辦法如下:

用 transform: translate3D 代替 top 與 left ,因為 top/left 會導致迴流,而 translate 只產生重繪,效能會更好,另外 translate3D 走的是 3D, 在手機瀏覽器器上會 GPU 加速。

onScroll 觸發的頻率和渲染的速度會存在跟不上的情況,所有這裡最好是自己實現一個滾動條,在 Table Body 上監聽 onWheel 事件,在滾動條上監聽 onMouse* 事件。 在自己實現滾動條的時候需要注意的是,在 Mac 的 chrome 上,左右滑動的時候會觸發瀏覽器的上一頁和下一頁功能,所以這裡的事件冒泡要處理好(本來想找一個開源的滾動條輪子,發現有好多元件這個問題沒有處理好,所以就自己寫了)。

減少scroll事件中的dom操作 

為了更好的對比table的scroll效能,通過對iview和element兩個元件庫的table均進行了5000行資料下table滾動的測試,發現兩者均有一定的抖動(都有做防抖動處理,不夠明顯)。

檢視兩個元件庫的原始碼,發現兩者均在scroll事件中執行了較多的邏輯判斷,例如iview在scroll中進行了column是否存在的判斷,時,每次渲染都對操作那一列進行了重新渲染計算,element在scroll時,對左右和上下的滾動都進行了判斷計算,這些也都影響滾動的效能。由於onscroll的高頻觸發,儘量減少scroll事件中對dom的計算和操作

,減少瀏覽器重排和重繪。

優化滾動事件

對於onscroll,onresize等這一類高頻觸發的事件,如果事件中涉及到大量的位置計算、DOM 操作、元素重繪等工作且這些工作無法在下一個 scroll 事件觸發前完成,就會造成瀏覽器掉幀。加之使用者滑鼠滾動往往是連續的,就會持續觸發 scroll 事件導致掉幀擴大、瀏覽器 CPU 使用率增加、使用者體驗受到影響。

對使用者來說,平滑的滾動往往能帶來很好的互動效果,優化滾動事件往往有以下三種方法:

  • 防抖(Debouncing):把多個操作合併為一個,即在一定時間內,規定事件出發的次數。
  • 節流(Throttling):只允許操作在一定時間內執行一次,只有當上一次操作執行後過了你規定的時間間隔,才能進行下一次。這種方法往往運用於圖片懶載入的的優化。
  • 使用 rAF(requestAnimationFrame)觸發滾動事件:在頁面重繪之前,通知瀏覽器進行操作。

一般來說,現有的table元件中,一般採用第一種方式來對scroll事件進行處理,通過約束一定時間內發生的次數,來因為使用者過快操作導致的scroll請求。

 

具體可以參考:https://segmentfault.com/a/1190000012568782