function VirtualList({ data, itemHeight, bufferSize = 5 }) {
const [scrollTop, setScrollTop] = useState(0);
const containerRef = useRef(null);
// 计算可视区域范围
const viewportHeight = containerRef.current?.clientHeight || 0;
const startIndex = Math.max(0, Math.floor(scrollTop / itemHeight) - bufferSize);
const endIndex = Math.min(data.length, startIndex + Math.ceil(viewportHeight / itemHeight) + bufferSize * 2);
// 动态渲染的条目
const visibleItems = data.slice(startIndex, endIndex);
return (
<div
ref={containerRef}
onScroll={(e) => setScrollTop(e.target.scrollTop)}
style={{ height: '100%', overflow: 'auto' }}
>
{/* 占位容器,模拟完整列表高度 */}
<div style={{ height: `${data.length * itemHeight}px` }}>
{/* 实际渲染的内容 */}
<div style={{ transform: `translateY(${startIndex * itemHeight}px)` }}>
{visibleItems.map((item, index) => (
<div key={item.id} style={{ height: `${itemHeight}px` }}>
{item.content}
</div>
))}
</div>
</div>
</div>
);
}
-
缓冲区(bufferSize):在可视区域外额外渲染少量条目,避免快速滚动时出现空白。
-
- 定高(itemHeight):提前确定条目高度(或使用动态高度预测),简化位置计算。
-
- CSS Transform :用
translateY替代top属性,利用GPU加速提升性能。
- CSS Transform :用