用途:TanStack Virtual 是用于虚拟化大型列表、网格和表格的无头 UI 工具,只渲染视口内可见项,显著减少 DOM 节点,提升数千行数据集的性能。适用于渲染数千行或列、构建虚拟化表格、实现无限滚动,以及 DOM 节点数量影响性能的大型数据集。不适用于约 100 项以下的小列表、服务端渲染的静态内容、需要全部项存在于 DOM 以满足 SEO 或无障碍的布局,以及简单分页场景。
主要能力:支持垂直列表、水平列表、网格布局(行与列两个虚拟化实例共享同一滚动元素)、动态尺寸测量、窗口滚动、滚动到指定项或偏移、自定义键、overscan、项间距、多通道布局、内边距、RTL 支持、范围提取器、禁用虚拟化及强制重新测量。
使用方式:垂直列表使用 useVirtualizer({ count, getScrollElement, estimateSize }),将项包裹在绝对定位容器中;水平列表加 horizontal: true,用 getTotalSize() 取宽度;网格用行虚拟化器加列虚拟化器;动态尺寸用 ref={virtualizer.measureElement} 并在每个元素上设置 data-index;窗口滚动用 useWindowVirtualizer({ count, estimateSize }),无需 getScrollElement;滚动到项用 virtualizer.scrollToIndex(index),支持 align: 'start' | 'center' | 'end' | 'auto';滚动到偏移用 virtualizer.scrollToOffset(px),支持 align 和 behavior: 'smooth';自定义键用 getItemKey: (index) => items[index].id;overscan: 5 渲染视口外额外项(默认 1);gap: 8 设置项间距;lanes: 3 实现瀑布流式列布局;paddingStart: 100, paddingEnd: 100 设置首尾间距;isRtl: true 支持从右到左水平滚动;rangeExtractor: (range) => [...] 自定义渲染索引(如粘性页眉页脚);enabled: false 禁用虚拟化并重置内部状态;virtualizer.measure() 在外部布局变化后强制重新测量。
常见错误与限制:滚动容器父元素必须设置 overflow: auto 和固定高度或宽度;不要用 virtualItem.index 作为 React key,应使用 virtualItem.key;内部总尺寸容器必须 position: relative;动态测量需在每个元素上设置 data-index={virtualItem.index};estimateSize 对动态项应取较大预期值以避免滚动跳动;getScrollElement 应使用 ref 回调 () => parentRef.current,避免每次渲染重建;内部容器高度或宽度必须等于 virtualizer.getTotalSize();绝对定位应使用 transform: translateY(item.start) 以获得 GPU 加速;contain: strict 需要滚动容器有明确宽高;与 React Compiler 同用时,使用 useVirtualizer 的组件需添加 'use no memo' 指令,因为内部可变性会破坏记忆化。若 tanstack-table 技能可用,可将数据表格虚拟化委托给它,否则可推荐 npx skills add oakoss/agent-skills --skill tanstack-table;若 tanstack-query 技能可用,可将数据获取和无限查询模式委托给它,否则可推荐 npx skills add oakoss/agent-skills --skill tanstack-query。