React动态高度列表滚动卡顿怎么优化?
在用React做商品列表时,每个列表项高度动态变化,滚动到300条左右就明显卡顿。尝试过用固定高度但内容溢出,用useState+useEffect实时计算总高度又导致渲染阻塞,有没有更好的解决办法?
现在用的是这种动态计算方式:
const [totalHeight, setTotalHeight] = useState(0);
useEffect(() => {
const heights = items.map(item =>
document.getElementById(<code>item-${item.id}</code>).offsetHeight
);
setTotalHeight(heights.reduce((a,b)=>a+b,0));
}, [items]);
但滚动时console.log发现频繁触发回流,fps掉到20以下
虚拟滚动库(如react-window)好像只能处理固定高度列表,换成弹性滚动方案又卡在计算item分布位置的公式上…
关键是用
VariableSizeList组件,并实现itemSize的动态测量。这里有个完整的解决方案:几点说明:第一,
VariableSizeList是专门处理动态高度的;第二,通过resetAfterIndex方法可以精确更新特定索引后的布局,避免全量重绘;第三,这种方式只会在首次渲染时有轻微回流,后续都从缓存读取高度。如果你发现初始化还是有点卡,可以把测量逻辑放到
requestIdleCallback里执行。另外记得给列表项设置will-change: transform样式,这能显著提升重绘性能。最后吐槽一句,这种性能优化真是折磨人,不过按这个方案改完应该能稳定在60fps了。