Skip to content

虚拟列表优化

遗留问题:

  • 动态高度
  • 白屏问题
  • 滚动事件触发频率过高

动态高度

在实际应用中,列表项目里面可能包含一些可变内容,导致列表项高度并不相同。例如新浪微博:

image-20240702084546314

不固定的高度就会导致:

  • 列表总高度:listHeight = listData.length * itemSize
  • 偏移量的计算:startOffset = scrollTop - (scrollTop % itemSize)
  • 数据的起始索引 startIndex = Math.floor(scrollTop / itemSize)

这些属性的计算不能再通过上面的方式来计算。因此我们会遇到这样的一些问题:

  1. 如何获取真实高度?
  2. 相关属性该如何计算?
  3. 列表渲染的项目有何改变?

解决思路:

  1. 如何获取真实高度?

    • 如果能获得列表项高度数组,真实高度问题就很好解决。但在实际渲染之前是很难拿到每一项的真实高度的,所以我们采用预估一个高度渲染出真实 DOM,再根据 DOM 的实际情况去更新真实高度。
    • 创建一个缓存列表,其中列表项字段为 索引、高度与定位,并预估列表项高度用于初始化缓存列表。在渲染后根据 DOM 实际情况更新缓存列表
  2. 相关的属性该如何计算?

    • 显然以前的计算方式都无法使用了,因为那都是针对固定值设计的。
    • 于是我们需要 根据缓存列表重写计算属性、滚动回调函数,例如列表总高度的计算可以使用缓存列表最后一项的定位字段的值。
  3. 列表渲染的项目有何改变?

    • 因为用于渲染页面元素的数据是根据 开始/结束索引数据列表 中筛选出来的,所以只要保证索引的正确计算,那么渲染方式是无需变化的。
    • 对于开始索引,我们将原先的计算公式改为:在 缓存列表 中搜索第一个底部定位大于 列表垂直偏移量 的项并返回它的索引
    • 对于结束索引,它是根据开始索引生成的,无需修改。

-EOF-

Released under the MIT License.