虚拟列表滚动时为什么会出现白屏闪烁?

利云的笔记 阅读 4

我在用 React 实现虚拟列表时,快速滚动经常看到白屏一闪,体验很糟糕。明明已经按可视区域渲染了,数据量也不大(大概 1000 条)。

我试过用 React.memo 包裹子项,也加了 key,但问题还在。是不是我的高度计算有问题?

const getItemHeight = (index) => {
  return 60; // 所有项高度固定
};
const visibleCount = Math.ceil(containerHeight / itemHeight);
const startIndex = Math.floor(scrollTop / itemHeight);
const endIndex = startIndex + visibleCount;
我来解答 赞 6 收藏
二维码
手机扫码查看
1 条解答
端木树萱
这种白屏闪烁大概率是因为你只渲染了刚刚好塞满可视区域的节点,没有任何富余。快速滚动的时候,浏览器滚动的速度往往快于 React 渲染新节点的速度,导致旧节点销毁了,新节点还没挂载出来,中间露出的就是容器底色。

一般这样处理,加个缓冲区。在可视区域的上方和下方额外多渲染几条数据,比如多渲染半个屏幕的高度或者固定的 5 到 10 条。这样当你滚动时,下一屏的内容其实已经在 DOM 树里准备好了,肉眼就看不出闪烁。

代码上主要改一下 startIndex 和 endIndex 的计算逻辑,引入一个 bufferCount:

const bufferCount = 5; // 缓冲区数量,根据实际情况调整
const startIndex = Math.max(0, Math.floor(scrollTop / itemHeight) - bufferCount);
const endIndex = Math.min(data.length, Math.floor(scrollTop / itemHeight) + visibleCount + bufferCount);


另外要注意,你的容器高度必须是固定的,且父容器要有 overflow: auto 或 scroll,不然计算会乱。如果加了 buffer 还是不行,检查一下是不是 itemHeight 和实际渲染的高度对不上,哪怕差 1 像素,滚久了也会累积出白屏。
点赞
2026-03-04 13:55