虚拟列表滚动时内容错位,如何解决?
我在给聊天列表做虚拟滚动优化时遇到了问题,当快速滚动到中间区域后,列表内容会出现几秒的错位闪烁,但过一会又恢复正常。
已经用react-window实现了基础虚拟列表,设置了itemSize为60,容器高度500px。尝试在scroll时手动计算offset:
const [offset, setOffset] = useState(0);
const handleScroll = (e) => {
const scrollTop = e.target.scrollTop;
setOffset(scrollTop % 60); // 按item高度取余
};
但发现当聊天消息包含图片时,实际item高度会超过60px,导致滚动位置计算错误。控制台没有报错,但视觉上出现内容错位和闪动,特别是滚动到包含长文本的item时更明显。
试过把itemSize改成变量动态计算,但这样会导致渲染区域不断变化,反而更卡顿。请问这种动态高度的虚拟列表该怎么处理?
react-virtualized的AutoSizer和CellMeasurer。核心思路就是让每个 item 的高度自己去测量,而不是手动指定固定高度。这样即使有图片或者长文本,也能正确计算高度。
简单贴个代码示例:
关键点说一下:
1.
CellMeasurerCache是用来缓存每个 item 的高度,避免重复测量。2.
CellMeasurer包裹你的 item,会自动测量实际渲染高度。3.
AutoSizer让容器能自适应宽度和高度。性能上不用担心,
react-virtualized做得比react-window更成熟,尤其是动态高度场景下更稳定。我自己用了这个方案后,滚动体验提升非常明显,再也不会出现错位闪烁的问题。最后提醒一句,别再去折腾手动计算 offset 或者动态修改 itemSize,太容易出问题了,相信我,我都试过,不值得。