如何順滑的展現大數據列表?

往往談到前端性能優化,大數據列表的呈現老是一個老生常談的話題。基於瀏覽器自己處理DOM的方式,一旦列表數據足夠大時,老是不可避免的出現CUP和內存佔用致使的卡頓問題,所以,針對大數據列表,只能使用特別的方式來呈現。javascript

面對這個問題時,直覺反應就是切分:切成小塊再呈現。好比,如今有10萬條數據,僅僅拿出前1000條呈現出來,隨着滾動條的滑動再逐步展現後面數據。然而,這種方式引發的列表高度變化會給用戶帶來很是糟糕的滑動體驗,不管是補充數據仍是把原列表換掉,使用起來跟標準滾動條差異很是大。所以,僅僅是切分還遠遠不夠。前端

定高

爲了防止列表高度變化帶來的滾動體驗問題,須要在大列表呈現時就先計算好高度。也就是說當要呈現10萬條數據時,即便只先呈現前1000條,10W條數據的總高度要先被算好並設置在最外層的容器上。目的是當滑動時,呈現的數據變化,但容器總高度不變,這樣體驗起來纔會和普通滾動條一致。java

給10萬條數據定高,就意味着你須要知道每一條數據呈現出來的高度是多少,在代碼實現層面,能夠拿出其中一條數據展現出來獲取其高度。如此一來,不但總容器的高度能肯定,每一條數據在縱座標的起始位置也能定下,爲後續的滑動展現提供基礎。node

經過單項定高

分組

一旦高度定下,就能夠根據滾動條的的位置展現或隱藏列表數據,但具體的代碼實現卻不得不考慮性能問題,由於須要遍歷整個列表逐個判斷,10W條數據遍歷一次也是特別大的運算,更糟糕的是,滾動條滑動的事件觸發是很是頻繁的。react

解決方案就是分組,即將100個或1000個劃分爲一組,以組爲單位進行判斷,同時,須要在定高時根據每一項高度計算出組的縱座標起始位置。如此一來,遍歷時以組爲單位大大減小了計算量,10W條數據,1000個爲1組,遍歷起來也就只有100組而已。git

分組後,滑動展現時即可以靈活制定展現規則,好比滾動條劃過當前組高度一大半之後展現下一組等。github

分組後的滑動展現預覽圖

分組算法

由於看了國外一篇寫大數據列表的文章有感,才寫了此文。值得一提的是,那篇文章中的分組方式很特別,利用二叉樹算法,一個簡潔遞歸就把數據分好了。算法

recursiveSplit =(data)=> {
    if(data.length / 2 > this.minimumStackSize) {
      let mid = Math.floor(data.length/2, 10);
      let node = { 
        parent: true,
        getParent: ()=> data,
        data: [this.recursiveSplit(data.slice(0, mid)), this.recursiveSplit(data.slice(mid, data.length+1))]
      }
      return node;
    }
    return {
      parent: false,
      data
    }
  }

做者最終Demo的效果如圖,相關連接我已貼在文章底部。瀏覽器

demo效果展現圖

結語

處理大數據列表的呈現,關鍵點有兩個,一是定高,二是分組。定高保證了選擇性呈現數據時滾動條的正常體驗,分組則處理了頻繁遍歷帶來的性能消耗。性能優化

參考資料:

https://medium.com/better-pro...

https://react-eternal-list.ri...

https://github.com/rinasm/rea...

相關文章
相關標籤/搜索