acrobat 下拉列表 逻辑_记一次 无限列表 滚动优化
背景
長列表優化, 是頁面性能優化中的一個比較常見的問題,也是面試中的常客。
剛好最近在的項目中, 遇到了一個長列表的性能問題,試過多種方案, 最后得以解決。
今天就給大家分享一下。
正文
場景描述
用戶需要批量修改 Product中 sku 的 映射關系,可以選擇的 Product 的 數量不限。
每一條sku 對應如下結構:
因為可以選擇的sku數量是不限的, 又不能分頁, 只能做到一個列表里。
于是, 長列表出現了。
剛開始的方案是做一個虛擬列表。
具體就是通過監聽sroll事件,每次滾動后計算一般元素位置(top和height)
然后,通過渲染三屏的方式,把一段數據渲染到頁面上。
數據量不多的時候, 沒什么問題。
當選擇幾百上千條sku 的時候, 快速滑動, 就開始出現卡頓。
如圖所示:
快速滾動出現空白作為對比,看一下優化后的效果:
優化之后問題定位
在chrome調試工具下,邊拖動列表邊觀察dom的變化。
發現,dom的卸載/掛載/更新的情況都出奇地慢,鼠標已經停下來,能明顯感覺到過一會dom才裝載完成,所以很可能是dom的渲染性能問題。
定位到渲染性能有問題的dom身上,即每一個 Item(renderFakeTable)。
使用普通文本代替Item,在同樣多數量的列表情況下,簡單的dom明顯會順暢很多,但是,仍然會出現空白問題。
繼續觀察renderFakeTable中的每一個元素(可以借用devTools Profiler)。
最簡單粗暴的方式就是去除某一類的組件,然后通過不斷自測的方式,找出最有可能影響渲染效率的元素:
SearchSelect(基于antd的Select封裝的一個業務組件)。
所以,影響渲染性能的元素很可能就是它。
渲染性能
除了組件的問題,還有可能是渲染的問題。
首先,原來無限滾動的邏輯就是基于scroll事件,通過不斷滾動觸發的回調,重新計算渲染到頁面上的區間。
其次,為了動態調整可視區域的元素,使用了MutationObserver。
導致空白問題則會有這幾種可能:
不幸運的是,以上的可能都一一排除后,發現幾乎沒有啥提升。
其實,在第二點縮小范圍時,應該意識到,空白問題/拖動不流暢均是因為渲染性能低下導致的
測試驗證
1. 虛擬列表 rc-virtual-list
為了驗證是Select 組件的問題,基于:
rc-virtual-list
做了一個在線 demo :????
在線地址:https://codesandbox.io/s/optimistic-bartik-69ygc?file=/src/animation.tsx
動態演示:
這里渲染了1000 條記錄, 每條記錄里有5個select;
默認使用的是 antd Select, 幾乎拉不動;
切換到原生select之后, 如絲般順滑。
由此可以確定,卡頓是 Slect 組件引起的。
所以要減少渲染成本:
2. 下拉懶加載
基于 Intersection Observer 實現一個 下拉懶加載。
利用 Intersection Observer 實現:
在列表的底部(也可能是底部偏上的某個位置)插入一個observer-dom元素.
通過Observer來觀測其是否在可視區域中,如果在,那么就往下加載更多的內容:
初始狀態時,列表會多渲染幾條數據(兩屏數據),observer-dom元素一直被頂到底部.
用戶往下滾動時,observer-dom元素“出現”在用戶視野。
每次多加載一屏的數據,循環如此,直到整個列表都渲染到頁面上。
在線demo: https://codesandbox.io/s/gundongjiazai-antd491-forked-vtchw?file=/index.js
動態演示:
選擇方案
最終采用下拉懶加載。
總結
通常,無限滾動的方案可以分為兩種:
1. 虛擬長列表
優點:可以保證渲染在頁面上的dom元素盡可能少
缺點:如果沒有特殊處理(比如rc或鎖定滾動區域),快速滾動時,基本都會有閃動的情況(也就是本次的空白問題)
2. 下拉懶加載
優點:防止用戶快速拖動的出現閃動問題。再通過加一個loading效果,幫助優化體驗
缺點:當用戶把列表拉到底,整個列表都會被渲染到頁面上
在選擇虛擬長列表or下拉懶加載之間的取舍時,可以參考:
如果閃動問題可以接受(組件渲染沒有太大性能問題),而且對dom數量要求很嚴格,那么選擇虛擬長列表會更好。
如果閃動問題不能接受,而最終的dom數量能夠接受,那么選擇下拉藍加載會更好。
無論是選擇虛擬長列表or下拉懶加載,在使用監聽scroll事件或者Intersetion Observer API之間的取舍時,可以參考:
- scroll的事件回調會在主線程中被成千上萬次調用,盡管加了防抖
- scroll的方式,需要不斷記錄scrollTop和元素高度
而使用Intersetion Observer API,上述幾點的計算就可以省略了,優化工作交給了瀏覽器。如果不考慮IE 等, 它是一個不錯的選擇。
內容就這么多, 希望對大家有所啟發。
如有錯誤, 歡迎指正, 謝謝。
總結
以上是生活随笔為你收集整理的acrobat 下拉列表 逻辑_记一次 无限列表 滚动优化的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: laravel 控制器 中间件 传递数据
- 下一篇: python自启动 绕过360_记录一次