react-tiny-virtual-list源码解析
本文最后更新于:2023年1月12日 下午
前言
所谓虚拟列表,就是只渲染用户能实际看到的内容,也就是我们所说的视口,对于超过视口的部分就不渲染,从而避免渲染元素过多造成页面卡顿,大概效果如下
源码解析
react-tiny-virtual-list
支持垂直和水平方向上滚动,通过组件提供的recomputeSizes()
方法,可支持加载动态高度的元素
部分参数分析
width
和height
根据滚动的方向设置列表的宽度或者高度itemCount
指定渲染列表的总数itemSize
支持纯数值,或者指定每一项元素高度的数据,或者一个返回高度的函数renderItem
渲染元素,其参数包含了当前元素的index
和style
overscanCount
要在可见项上方/下方渲染的额外缓冲区项数。调整此项可以帮助减少某些浏览器/设备上的滚动闪烁。estimatedItemSize
估算的元素高度,用来支持动态高度
代码实现
首先我们看下组件的render()
方法的实现
1 |
|
可以看到,这里最主要的操作是获取当前要渲染的元素,而这个操作是通过this.sizeAndPositionManager.getVisibleRange()
函数计算出来的,而this.sizeAndPositionManager
是在组件初始化时由SizeAndPositionManager
创建的实例
1 |
|
SizeAndPositionManager
是一个工具类,用于处理列表元素的信息,其构造函数,用于初始化一些变量,其中this.itemSizeAndPositionData
用于缓存item
的size
和offset
,this.lastMeasuredIndex
用于保存最后一个计算元素时的index
1 |
|
getVisibleRange()
是用来获取当前渲染元素的start index
和stop index
1 |
|
组件在componentDidMount
生命周期中,为容器组件挂载了滚动事件,用于处理滚动。当滚动触发时,去更新offset
状态,从而触发新的计算后重新渲染元素
1 |
|
总结
通过对源码的分析,可以看出,根据start
和stop
就可以计算出当前需要渲染的元素,要得到start
值,就需要计算元素的偏移量(offset)
,若要得到stop
,需要将start
之前的偏移量(offset)
再加上容器的高度或宽度。在滚动时,需要监听容器的scroll
事件,容器的scrollTop/scrollLeft
就是当前要展示在容器中的元素的偏移量(offset)
,然后再用前面的计算方式,就可以得到新的start
和stop
参考
https://www.jianshu.com/p/39404c94dbd0