前端虚拟列表实现:避免一次性渲染大量 DOM 节点
背景与问题
前端开发中,处理长列表数据时若一次性渲染所有项(如 10000 个),会导致页面卡顿甚至崩溃。例如一个下拉列表有 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. 基础虚拟列表实现
// 正确姿势:基础虚拟列表
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, : }));
;
}


