
前端UI组件【免费下载链接】rsuite A suite of React components .项目地址https://gitcode.com/gh_mirrors/rs/rsuite点击查看免费下载导读在 React 组件库 rsuite 中当需要渲染数千乃至上万条数据如CheckPicker、SelectPicker、Tree等组件的候选列表时虚拟化是保证性能的关键手段。本文以仓库内类型文档 list-props.md 为骨架深入讲解 rsuite 虚拟化列表的核心接口ListProps的四个字段——itemSize、initialScrollOffset、onItemsRendered、onScroll——并结合 Windowing/List.tsx 的源码实现与官方示例给出可直接落地的配置方案。读完本文你将掌握虚拟化列表的尺寸策略、初始定位、滚动监听与无限加载等实战能力。一、ListProps虚拟化列表的统一接口rsuite 将底层虚拟化能力封装为内部组件 src/internals/Windowing/List.tsx该组件基于react-window的VariableSizeList构建并对外暴露统一的ListProps接口。类型文档 docs/pages/_common/types/list-props.md 中给出了其精简定义interface ListProps { /** * Size of a item in the direction being windowed. */ itemSize?: number | ((index: number) number); /** * Scroll offset for initial render. */ initialScrollOffset?: number; /** * Called when the items rendered by the list change. */ onItemsRendered?: (props: ListOnItemsRenderedProps) void; /** * Called when the list scroll positions changes, as a result of user scrolling or scroll-to method calls. */ onScroll?: (props: ListOnScrollProps) void; }需要注意的是这份文档是精简后的「类型摘要」在真实源码 src/internals/Windowing/List.tsx#L17-L70 中ListProps还扩展了react-window的BaseListProps并额外支持width、itemKey、scrollShadow、height等字段。上述四个字段正是虚拟化列表最核心、也最常在业务中直接使用的部分。1.1itemSize列表项尺寸固定值或动态函数itemSize表示「被窗口化方向上每个条目的大小」即纵向列表中每行的高度横向列表则为每列的宽度。它可以是固定数值所有条目高度一致例如itemSize: 36函数(index: number) number根据索引返回对应条目的高度用于不定高场景。源码 Windowing/List.tsx#L122-L128 对两种形态做了归一化处理数值会被包装为() itemSizeProp的常函数函数则原样透传最终统一交给react-window的VariableSizeListconst itemSize useMemo(() { if (typeof itemSizeProp function) return itemSizeProp; return () itemSizeProp; }, [itemSizeProp]);同时仓库内置了默认行高常量defaultItemSize () 36见 Windowing/List.tsx#L15即未显式指定时按 36px 计算这也是各 Picker 虚拟化列表的基准行高。兼容性提示旧版本中的rowHeight已被标记为deprecated use itemSize instead见 Windowing/List.tsx#L30-L34。为保持兼容源码仍会将其转换为itemSize见 Windowing/List.tsx#L115-L132但新代码请统一使用itemSize。1.2initialScrollOffset首屏初始滚动偏移initialScrollOffset用于指定列表首次渲染时的滚动偏移量常见于「打开面板后直接定位到某一行」的需求。例如日历组件的月份下拉面板在 src/Calendar/MonthDropdown/MonthDropdown.tsx#L102-L128 中就是根据当前年份与起始年份的差值计算initialItemIndex再乘上ITEM_SIZE得到初始偏移从而让月份面板打开时自动定位到当前月份const initialItemIndex getYear(date) - startYear; const initialScrollOffset ITEM_SIZE * initialItemIndex; // ... initialScrollOffset{initialScrollOffset}由于它只作用于首次渲染适合「打开即定位」若需要在运行中动态滚动到指定行则应使用下文介绍的ListHandle.scrollToItem等命令式方法。1.3onItemsRendered渲染条目变化回调onItemsRendered在列表「当前渲染了哪些条目」发生变化时触发回调参数ListOnItemsRenderedProps包含visibleStartIndex、visibleStopIndex、overscanStartIndex、overscanStopIndex等字段源自react-window。这是实现**无限加载infinite loading**的核心钩子。官方示例 select-picker/fragments/infinite-loader.md 展示了完整用法当可见区最后一个索引接近数据末尾时自动追加下一页数据const onItemsRendered props { if (props.visibleStopIndex data.length - 1) { loadMore(); } }; return ( SelectPicker data{data} w{224} virtualized renderListbox{renderListbox} listProps{{ onItemsRendered }} / );visibleStopIndex是当前可视区域最后一个条目的索引当它逼近data.length - 1即意味着用户已经滚动到底部此时触发异步加载loadMore()并配合renderListbox在列表底部渲染一个加载指示器Loader形成完整的「滚动到底 → 加载更多」闭环。1.4onScroll滚动位置回调onScroll在列表滚动位置发生变化时触发参数ListOnScrollProps主要包含scrollDirection滚动方向、scrollOffset当前滚动偏移、scrollUpdateWasRequested是否为代码触发的滚动等字段。它适用于记录/恢复滚动位置联动其他 UI如吸顶头、进度指示区分用户滚动与scrollTo命令式滚动通过scrollUpdateWasRequested判断。与onItemsRendered一样onScroll同样通过listProps透传给底层的react-window列表属于被动监听型回调不会触发额外渲染开销。二、这些属性在哪里生效listProps的透传链路ListProps在 rsuite 中并不单独直接使用而是通过各 Picker/树形组件的listProps属性透传。启用虚拟化的前提是组件开启virtualized随后将上述属性以对象形式传给listProps。以CheckPicker为例其官方属性表见 check-picker/en-US/index.md#L128明确记载属性说明virtualized是否启用虚拟化长列表listProps虚拟化长列表的相关属性即ListProps同样的listProps透传机制也存在于SelectPicker、InputPicker、TagPicker、Tree、CheckTree、TreePicker、CheckTreePicker等组件的文档中。因此凡是遇到「候选数据量庞大导致渲染卡顿」的场景都可以用同一套ListProps配置来优化。一个直观的示例是 check-picker/fragments/virtualized.md——仅需开启virtualized即可流畅渲染 10000 条数据const data Array.from({ length: 10000 }).map((_, index) ({ label: Item ${index} is a long text, Used to test the virtualized list., value: Item ${index} })); const App () ( CheckPicker data{data} w{224} virtualized / );从源码链路看Picker 内部将listProps交给 Windowing/List.tsx 封装的列表组件后者再将itemSize、initialScrollOffset、onItemsRendered、onScroll等透传给react-window的VariableSizeList并自动注入direction依据useCustom()的 RTL 配置见 Windowing/List.tsx#L137保证中文等 RTL 场景下的滚动方向正确。三、进阶通过ListHandle命令式控制滚动除了通过initialScrollOffset做首屏定位外虚拟化列表还通过ref暴露了ListHandle命令式接口见 Windowing/List.tsx#L72-L113方法说明scrollTo(scrollOffset)滚动到指定偏移量scrollToItem(index, align?)滚动到指定索引的条目align支持auto/smart/center/end/startresetAfterIndex(index, shouldForceUpdate?)从指定索引开始重新计算尺寸用于动态高度变化后刷新scrollToRow(index)已废弃请使用scrollToItem在 tree/fragments/virtualized.md 与 check-tree/fragments/virtualized.md 中官方给出了「点击按钮跳转到指定节点」的典型用法listRef.current?.scrollToItem(index, auto);配合scrollShadow属性滚动时列表顶部/底部还会渲染阴影提示由内部ScrollView实现见 Windowing/List.tsx#L80-L82提升滚动体验的可见性。四、与List排序组件的区分仓库中存在两套List相关实现容易混淆需特别注意src/internals/Windowing/List.tsx本文主角虚拟化长列表供各 Picker/Tree 的listProps使用属性即ListPropssrc/List/List.tsx面向展示与拖拽排序的List组件支持sortable、bordered、hover、divider等其同名ListProps与虚拟化无关。两者共享ListProps命名但语义完全不同阅读源码或检索文档时请以文件路径为准。本文所有属性说明均指前者虚拟化列表。五、实战要点小结固定高度优先条目高度一致时直接传数值如itemSize: 36性能最好动态高度再改用(index) number函数。打开即定位用initialScrollOffset它只在首屏生效适合初始化定位动态跳转请用ListHandle.scrollToItem。无限加载用onItemsRendered监听visibleStopIndex逼近末尾时加载下一页注意加载期间避免重复触发。滚动联动用onScroll读取scrollOffset与scrollUpdateWasRequested区分用户滚动与程序滚动。统一入口是listProps先开启virtualized再把上述属性放进listProps对象适用于所有支持虚拟化的 Picker 与树组件。以上所有结论均可回溯到仓库源码类型定义见 docs/pages/_common/types/list-props.md实现见 src/internals/Windowing/List.tsx实战示例见 select-picker/fragments/infinite-loader.md、check-picker/fragments/virtualized.md 与 tree/fragments/virtualized.md。赞分享前端UI组件【免费下载链接】rsuite A suite of React components .项目地址https://gitcode.com/gh_mirrors/rs/rsuite点击查看免费下载相关推荐BetterDiscord虚拟列表长列表渲染优化方案BetterDiscord虚拟列表长列表渲染优化方案 在Discord增强客户端BetterDiscord中插件和主题管理界面经常需要处理大量项目的展示。当桌面应用UI组件ant-design虚拟滚动大数据列表渲染优化ant design虚拟滚动大数据列表渲染优化 在企业级应用开发中我们经常会遇到需要展示大量数据列表的场景比如展示上万条用户数据、订单记录等。如果直接渲染前端UI组件设计系统Eve虚拟滚动列表大数据集渲染优化Eve虚拟滚动列表大数据集渲染优化 你还在为加载十万条数据时页面卡顿发愁吗当用户滚动列表时传统渲染方式会一次性创建所有DOM节点导致内存占用飙升和滚动掉编程语言上一篇Lockbox 开源项目使用教程下一篇告别臃肿控制中心G-Helper让你的华硕笔记本重获新生创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考