用戶
 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

掃一掃,登錄網站

小程序社區 首頁 教程 查看內容

解決小程序渲染復雜長列表,內存不足問題

Rolan 2019-12-9 00:12

問題回顧:我們有一個列表展示頁,是無限瀑布流式的,展示的元素我們封裝成了單個組件,暫且叫它Item組件。這個瀑布流包含若干個Item組件,并且這個Item組件也比較復雜,包含各種展示樣式(根據不同類型,大概有9種 ...

問題回顧:我們有一個列表展示頁,是無限瀑布流式的,展示的元素我們封裝成了單個組件,暫且叫它Item組件。這個瀑布流包含若干個Item組件,并且這個Item組件也比較復雜,包含各種展示樣式(根據不同類型,大概有9種吧,反正渲染節點很多),在進行滑動的過程中,item大概加載30-40個以后,就會造成小程序內存不足而退出,藍瘦香菇......【干貨在最后,小程序代碼片段奉上】

解決思路:

將超出屏幕一定部分的列表內的組件進行不渲染的處理(也就是用wx:if卸載掉組件),當到達渲染臨界點時再開始渲染;保證每次少量的數據展示。

我們的項目中是保持15條Item,我們是每次分頁請求5條,按照前5條,中間5條和后5條來劃分,如果不在這個范圍,則用一個等高度的骨架代替,并且卸載這些組件

初期實現方式(后面有更優化的方式)

使用曝光監聽,當一個Item曝光時,記錄Item高度,并放到數組里面,作為骨架的填充高度,如果已經記錄了高度,則不再重復記錄;曝光時向外傳遞一個當前渲染范圍的中心值(比如當前Item所屬頁碼,或者當前Item索引),以此進行處理;

這里有一點要注意,如果你的列表item組件比較復雜,需要在ready的時候將記錄的高度設置為item最小高度,不然組件重新裝載時會有一定的渲染時間,在臨界點會造成跳屏【此處已經通過骨架組件解決,可以忽略,只是作為踩坑記錄】

此時優化點

  • 為避免頻繁setData和渲染,做了防抖函數,時間是600ms

此時缺點

  • 滑動特別快時,會出現白屏,是因為曝光監聽是在組件里面,而超快速滾動時,組件沒有裝載進來,也無法進行曝光監聽,所以無法觸發,這里考慮用骨架組件進行二次監聽曝光

優化迭代

  • 將骨架組件作為外殼套在Item外面(用slot),并對骨架進行監聽曝光,可以解決上面缺點
  • 給骨架組件做一個常規骨架屏樣式,而不是純白色,看起來更優雅

繼續發現問題

經過一系列的實踐,上面的方案有些問題,其中最麻煩的就是,需要對外傳遞一個當前index,然后控制前后數據展示;這里對于每個用到skeleton組件的頁面來說,都要重復的寫一個方法來承接這個index,然后渲染頁面對應的數據。

優化

依然是監聽skeleton曝光,這里監聽的方案變為出現在屏幕上下n屏的內容塊進行展示,此范圍外的內容塊就卸載掉。

如圖所示


核心代碼

     // 修改了監聽是否顯示內容的方法,改為前后showNum屏高度渲染
     // 監聽進入屏幕的范圍relativeToViewport({top: xxx, bottom: xxx})
      let info = SystemInfo.getInfo() //獲取系統信息
      let { windowHeight = 667 } = info.source.system
      let showNum = 2 //超過屏幕的數量,目前這個設置是上下2屏
      let listItemContainer = this.createIntersectionObserver()
      listItemContainer.relativeToViewport({ top: showNum * windowHeight, bottom: showNum * windowHeight })
        .observe(`#list-item-${this.data.skeletonId}`, (res) => {
        	// 此處來控制slot展示,詳見代碼片段
        })
       
復制代碼

干貨

話不多說,干貨放后面,點擊獲取代碼片段

最后,還是盡量減少節點數,優化代碼

鮮花
鮮花
雞蛋
雞蛋
分享至 : QQ空間
收藏
原作者: 宗仔GEG 來自: 掘金
必中分分彩在线计划 南昌麻将十三烂规则 单机大众麻将下载 北京一赛车开奖直播 一级a做愛片免费观看 室外篮球场 微乐河南麻将怎么玩 快3二同号中奖多少钱 江西老十一选五走势 网上的五分彩是真的 北京快3走势图和值分析 支付宝的天天红包赛 南京麻将手机版 福建快3网上买 qq分分彩在线计划 闲来长沙麻将下载 3d字谜藏机图正版