小程序长列表有终极方案吗

121 阅读2分钟

问题描述

大家或多或少都知道长列表会出现性能问题

一个列表页面,假设一次加载10条数据,滚动页面,触底加载后10条。每条数据展示在页面上有很多节点。一直操作滚动触底加载,页面慢慢卡顿崩溃,并且出现dom limited……超出dom 节点限制的报错。

image.png

问题分析

在合理使用setData的前提下,页面的节点数也不能超出1000个,详见文档

image.png

随着不断触底加载,某一时间点就会达到限制,导致页面崩溃。

解决的方向就是,数据量多的情况下,怎么控制页面的节点数

 

方案

一顿百度猛如虎后,发现实现的逻辑就是,不在屏幕可见区域的数据,不渲染节点,用一个相同高度的view撑开。

image.png

  关键就是,怎么判断可见不可见?

一、createIntersectionObserver

节点布局交叉状态 API,用于监听两个或多个组件节点在布局位置上的相交状态。见文档

developers.weixin.qq.com/miniprogram…

常常用于推断某些节点是否可以被用户看见

image.png

 

参考:

juejin.cn/post/684490…

 

二、页面滚动时监听

  • 列表数组改成二维数组
  • 一次渲染一屏10条,用createSelectorQuery 计算一屏的总高度
  • 滚动时,滚动高度realScrollTop + 当前屏幕的高度this.windowHeight 和每一屏的高度比较,就能知道当前哪一屏是可见的

参考zhuanlan.zhihu.com/p/146791824

 

疑问

一、不管是用现成组件还是自己实现,底层逻辑都是判断不可见时用高度占位。假如真的无限加载都有数据,在可见区域真实渲染的节点有200个(假设),高度占位的区域有800个,不是也会超出dom节点限制吗?

二、列表页不是纯静态的,类似朋友圈一样有评论点赞删除发布,执行操作之后又要去判断可见与否

image.png  

所以有终极解决方案吗?哪里是我没想通的一点呢?