為啥使用長列表
需要展示長列表,無限下拉都會一直顯示出更多的數據。但是當一個頁面展示的DOM節點過多的時候,會造成小程序頁面的卡頓,點擊反應遲鈍,嚴重的會直接白屏。
原因有幾點
- 列表數據很大,不斷獲取下一屏的數據,setData的數據越來越多的時候耗時高
- 渲染DOM 結構多,每次 setData 都需要創建新的虛擬- 樹、和舊樹 diff 操作耗時都比較高
- DOM 結構多,占用的內存高,造成頁面被系統回收的概率變大,會白屏
首先想到的是使用二維數組
- 首先開始是每次渲染數據都重新進行push,然后setData賦值,但是這樣做的效果是數據過多時就會出現卡頓,白屏
- 於是着手把數據變成二位數組,setData時只對當前索引賦值這樣的好處是可以減輕setData數據
本以為這樣的話可以解決但是試了試數據過大時仍然卡頓,dom渲染還是很多,於是只渲染在當前屏幕的,其他位置用空標簽占位
解決方案:
方案1
<block >
<block
wx:for="{{infoList}}"
wx:for-item="infoItemList"
wx:for-index="pageNum"
wx:key="pageNum">
<info-item
custom-class="info-item"
useCustomSlot="{{false}}"
wx:for="{{infoItemList}}"
data-index="{{index}}"
data-page="{{pageNum}}"
wx:key="id"
info="{{item}}"
>
</info-item>
</block>
</block>
- 有兩層循環,第一層循環最外層的(二維數組索引),第二層循環每屏數據info-item是封裝的每個item展示數據
- 現在做的就是在這上面優化讓在視圖內的顯示數據,不在試圖內的讓view標簽占位
- 接着我們存儲每屏高度,然后記錄滾動距離,獲取現在應該渲染那幾屏 滾動距離
根據這個滾動距離以及每一屏的高度,來計算當前應該渲染哪一屏的數據。這個需要怎么去算?其實很簡單,循環去遍歷每屏高度,用第一屏的高度 與滾動高度 + 當前屏幕的高度this.windowHeight做比較,如果滾動高度比較小,則用第一屏累加第二屏的高度,一直到第一屏幕累計高度 > 滾動高度 + this.windowHeight 就是當前應該渲染的屏幕。
方案2:
wx.createIntersectionObserver
