前端虚拟列表实现
问题背景
在处理大量数据列表时,一次性渲染所有节点会导致页面卡顿甚至崩溃。例如,一个包含 5000 个选项的下拉列表,若全部渲染,会严重消耗浏览器资源。
反面示例
// 错误做法:一次性渲染所有数据
function BigList({ items }) {
return (
<ul style={{ height: '400px', overflow: 'auto' }}>
{items.map(item => (
<li key={item.id} style={{ height: '50px' }}>
{item.name}
</li>
))}
</ul>
);
}
// 使用
<BigList items={Array.from({ length: 10000 }, (_, i) => ({ id: i, name: `Item ${i}` }))} />
渲染 10000 个 DOM 节点会显著增加内存占用和重绘开销,影响用户体验。
实现方案
1. 基础虚拟列表实现
通过计算可见区域,仅渲染视口内的元素,并利用 transform 进行偏移。
import { useState, useRef, useMemo, useCallback } from 'react';
function VirtualList({ items, itemHeight, containerHeight }) {
[scrollTop, setScrollTop] = ();
containerRef = ();
visibleCount = .(containerHeight / itemHeight);
totalHeight = items. * itemHeight;
startIndex = .(scrollTop / itemHeight);
endIndex = .(startIndex + visibleCount + , items.);
visibleItems = ( {
items.(startIndex, endIndex);
}, [items, startIndex, endIndex]);
offsetY = startIndex * itemHeight;
handleScroll = ( {
(e..);
}, []);
(
);
}
() {
items = .({ : }, ({ : i, : }));
;
}


