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`,平滑加载
  • 估算高度与占位,避免回流抖动
  • 回收不可见项的资源与事件,降低开销


点赞(0) 打赏

评论列表 共有 0 条评论

暂无评论
立即
投稿

微信公众账号

微信扫一扫加关注

发表
评论
返回
顶部