开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第7天,点击查看活动详情
最近在学习掘金小册《React进阶实践指南》,其中介绍到了React对应海量数据的处理方案,本文将对其中介绍的方法进行实践与记录。分别从时间分片、虚拟列表两方面着手。
时间分片
时间分片本质上就是将所有任务分割成多个子任务来实现,最主要是因为浏览器执行JS的速度相比于浏览器渲染DOM的速度来说就很快了。
比如如下实现一个小demo,一次性加载10000个dom元素,如果不做任何处理,那么页面加载是很慢的,因为一次性渲染10000个dom是很耗费性能的,最后等到所有元素加载完毕,会突然出现在页面上,给用户的体验也不太好。
所以可以考虑使用时间分片的方法,主要步骤分为三步:
1、计算总共可以分为多少个时间片,按照每个时间片长度为200,即每次需要渲染200个don元素,用10000 / 200 = 50
,得到需要渲染50次,分为50个时间片。
2、开始渲染数据,通过index>times
判断是否渲染完成,如果没有渲染完成,那么通过requestIdleCallback
代替setTimeout
浏览器空闲执行下一帧渲染
3、最后通过渲染的方法renderList
将已经渲染的元素进行缓存。
虚拟列表
虚拟列表是一种长列表的解决方案,将出现在可视区域内的数据才进行渲染,而未出现在可视区域内的数据则不进行渲染,这样就不会造成一次性渲染大数据量的元素了。
虚拟列表划分可以分为三个区域:视图区 + 缓冲区 + 虚拟区。缓冲区是为了防止用户在滑动过程中,出现白屏、跳动等效果。虚拟区就是未渲染的区域。
具体实现思路如下:
- 通过
useRef
获取元素,并缓存变量。 - 使用
useEffect
初始化计算容器的高度、截取初始化列表长度,使用div元素进行占位,从而撑起滚动条。 - 通过监听滚动容器的
onScroll
事件,根据scrollTop
来计算渲染区域向上偏移量. - 最后通过重新计算 子项的
end
和start
获取应该出现在可视区域内元素的索引来重新渲染列表。