聊一聊 React 的 virtual scroll

View Post on Blog

也没啥高见,重复一下网上现有的资料而已


Virtual scroll 解决了什么问题

Virtual scroll 是绘制超大型列表的性能解决方案。众所周知当 DOM 元素变得很多的时候,渲染元素将消耗可观的时间。即使元素是分配获取、绘制的,浏览器的内存消耗、计算元素位置的 CPU 消耗等也会上升,列表滚动及其他操作的延迟就会增加。

Virtual scroll 是怎么做的

正如某相关模块 react-window 的名字,你是通过一扇窗户来看这个大列表,也只有窗户里的东西才会绘制(当然可以设置余量 overscan)。

其他解决方案的问题

(没错,我只知道 LazyLoad)

Lazyload

对于 React 而言,react-lazyload 中需要 lazyload 的元素呆在同一个列表中,这意味着如果一个页面有两个列表,一个的滚动将引起另一个列表内元素的重新计算。而且如果你有一个 overflow: scroll 的列表和一个随页面滚动的列表,将引起事件处理的混乱。

一般来说,LazyLoad 并没有解决 DOM 元素数量级的问题,只是把复杂的元素变得简单,到时候再绘制。如果有大规模筛选列表的操作,Unmount LazyLoad component 也是一笔不小的开支。

如果滚动到很下方,对上面的元素如何处置又是一个问题。Unmount 吧,滚动位置会突变;hide 吧,实质作用并不大,仍然参与计算,内存也占用着。

Virtual scroll 的难点及 React 现有模块简评

这里主要针对列表元素高度未知(dynamic,动态,与随时间变化不同),画出来才知道的情况。固定高度的可以简单搞定。

react-window 也是一个好模块,但是动态功能难产,就一笔带过了。

基本问题

如何确定每个元素的位置是个难题,如果要求处理 resize (滚回去元素高度会变化)就更难了。

如果你还要求滚过的元素记住状态,对不起,自己实现或者弃坑。

没有浏览器加持,布局受限

平常做点网页的效果只需要 CSS 什么的就可以搞定。但是这里全靠手动,还不一定能成功 🤷‍♂

复杂算法,体积庞大

如果还要装作列表是随页面滚动的呢?什么?还要一起滚动的表头和表尾?表头还不能 unmount?……一堆需求下来,就有了体型庞大的 react-virtualized (35 KB min+gzipped) (虽然支持一定程度的 tree-shaking)

性能和懒难以兼得

本来就是为了性能才使用 virtual scroll 的(大雾

比如 react-virtuoso 虽然可以支持大小随时间变化,但是估计是加了元素大小变化事件监听,快速滚动下来明显不如 react-virtual 顺畅,甚至可以看到表尾不呆在应该有的底部。

bug 和问题频出

(看了 Issue 区就有点劝退了)

简单讲一个 react-virtual 碰到的问题。因为元素高度会变化,在图片加载后让 react-virtual 重新计算。但是重新计算意味着把所有元素的高度都看做是估计值。将会出现多次尝试绘制,再次触发的重新计算甚至引起绘制的死循环。同时滚动会出现跳跃。。😭

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值