Java教程

一文搞懂长列表优化和虚拟滚动

本文主要是介绍一文搞懂长列表优化和虚拟滚动,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!

写在前面

还 ⭐ 的基于 react-hooks 和 react-virtualized 写的虚拟滚动搭配上拉下滑加载的 scroll 组件
🌟🌟 github.com/DavidWong97… 🌟🌟
写出来的小玩意可能不是特别完美,如果能给大伙们提供到思路或者帮助,实在不胜荣幸
也希望大伙们给个 star 啦~

antd中的list-view

相信用过 antd-mobile 的小伙伴都知道里面的 ListView 组件
组件还算是能满足很多需要的
但遇到数据量大时可能就不太够用了
而且一些不熟悉 useMemo 的小伙伴对于 ListView 的优化可能会不知所措
所以我就封装了一个不需要自己优化 renderRow,又能做到虚拟滚动,又能满足 ListView 基本需要的组件
接下来就一步步拆解,如何实现这个组件😈
复制代码

什么是虚拟滚动

1. 背景<br>
    当遇到数据量大的列表渲染,如10万条数据,一次性渲染十万个元素,内存消耗肯定是裂开的<br>
    这时候考虑怎么展示完列表,又能优化性能提升体验 —— 虚拟滚动
2. 效果描述<br>
    创建一个容器,容器内部展示固定数量的数据,通过前后索引确定渲染数据的哪个区间
复制代码

react-virtualized原理剖析

1. 找出渲染区间
        a. startIndex: Math.max(0, startIndex - threshold),
        b. stopIndex: Math.min(rowCount - 1, stopIndex + threshold)
        c. threshold为列表项目数,默认15
2. 触发渲染
    _invokeRendered【渲染列表】
        a. componentDidMount
        b. componentDidUpdate
3. 对比后渲染
    每次渲染会缓存上一次的属性,若属性【如index】不一样,重新渲染
复制代码

长列表实现

1. 构成:refresh + virtualScroll + loadMore
2. 状态控制 STATS
    a. init - 初始状态
    b. dragging - 拖动中
    c. pre-refresh - 拖动达到最大限制,刷新状态就绪
    d. not-enough - 拖动未达到最大限制
    e. refreshing - 松手,正在刷新
    f. success - 刷新成功
3. refresh 实现
    a. onTouchStart
        记录startY,若状态为refreshing或success,不执行
        若scrollTop不为0,不执行
    b. onTouchMove
        计算logo的offset -> 当前pageY - startY
        根据条件设置offset
            ① 0 < offset && offset <= 下拉最大限制,设为计算得出的offset
            ② offset < 0,设为0
            ③ offset > 下拉最大限制,设为下拉最大限制
        
        若 offset >= 下拉最大限制,状态设为pre-refresh
        否则若 offset < 下拉最大限制,状态设为dragging
    c. onTouchEnd
        若STATS为 pre-refresh
            有传入回调onPullDown则调用,状态变更为 refreshing
            回调执行完,状态变更为 success,延迟后变为init
        否则
            状态变更为 not-enough,延迟后变为init
4. virtualScroll 实现
    a. 渲染传入的自定义组件children
    b. 若传入data有数据,渲染vList
5. loadMore 实现
    vList 中的 rowRenderer
        ① 传入对应的参数给 row 组件并渲染
        ② 根据状态渲染loading和没有更多的展示
6. onScroll回调封装一层
    a. 有传入onScroll,执行回调onScroll
    b. 有传入onPullUp
        若 clientHeight + scrollTop === scrollHeight
        则到达底部,执行回调onPullUp
复制代码

长列表rowRender优化

  1. 如果不作useMemo优化,列表数据其中一项只要更改,列表所有项都会重新渲染,造成性能浪费
  2. 对于传入的rowRender,需要独立声明一个组件包着再作渲染
  3. 判断的方式这里有些取巧了,直接JSON.stringify数据作判断
const Row = ({ row, data, index, info }:any) => {
  return useMemo(() => row({ data: data, index, info }), [JSON.stringify(data[index])])
}
复制代码

写在后面

看到这里的小伙伴,有没有觉得实现个长列表其实也很简单呢~
文中的解析再对照着项目中的代码看,相信你一定有所收获
还有~~~别忘了👍~⭐~👍~⭐~👍~⭐~👍~⭐~👍~⭐~👍~⭐~👍~⭐~👍~⭐~👍~⭐~
复制代码
这篇关于一文搞懂长列表优化和虚拟滚动的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!