IntersectionObserver 与虚拟列表性能优化:可见性检测、回收与占位策略
技术背景
当列表项数量巨大时,完整渲染会造成严重的性能问题。虚拟化通过仅渲染可见区域项并回收不可见项,降低 DOM 与绘制开销。IntersectionObserver 为可见性检测提供高性能事件源。
核心内容
观察器与项挂载
class VList {
private io: IntersectionObserver;
private container: HTMLElement;
private items: { id: string; el: HTMLElement }[] = [];
constructor(container: HTMLElement) {
this.container = container;
this.io = new IntersectionObserver((entries) => {
entries.forEach((entry) => {
const el = entry.target as HTMLElement;
if (entry.isIntersecting) this.mount(el);
else this.recycle(el);
});
}, { root: container, rootMargin: '100px' });
}
observe(el: HTMLElement) { this.items.push({ id: el.dataset.id || '', el }); this.io.observe(el); }
mount(el: HTMLElement) { el.dataset.mounted = '1'; }
recycle(el: HTMLElement) { el.dataset.mounted = '0'; }
}
占位与高度估算
function placeholder(height: number) {
const div = document.createElement('div');
div.style.height = `${height}px`;
div.className = 'placeholder';
return div;
}
技术验证参数
在 Chrome 128/Edge 130(大量项滚动场景):
- DOM 节点数量:下降 80–95%
- 滚动帧率:≥ 60fps
- 内存占用:下降 40–70%
应用场景
- 无限滚动与海量列表
- 图片墙与卡片集合
最佳实践
- 适度拓展 `rootMargin`,平滑加载
- 估算高度与占位,避免回流抖动
- 回收不可见项的资源与事件,降低开销

发表评论 取消回复