长列表滚动卡顿,怎么优化内存占用?
我用 React 渲染一个上千条消息的聊天列表,虽然用了虚拟滚动,但内存还是涨得特别快,页面越滚越卡。是不是没清理掉不可见的 DOM 节点?
目前是用 react-window 的 FixedSizeList,每个 item 是个函数组件,里面还用了 useMemo 包裹内容。但 Chrome 内存快照里看到很多 detached DOM 节点,不知道是不是哪里引用没释放。
关键代码大概这样:
const MessageItem = React.memo(({ data, index }) => {
const message = data[index];
return (
<div className="message">
{message.text}
</div>
);
});
// 列表渲染
<FixedSizeList
height={600}
itemCount={messages.length}
itemSize={60}
itemData={messages}
>
{MessageItem}
</FixedSizeList>
另外 itemData 如果每次渲染都是新数组引用,会导致所有 item 重渲染,内存肯定炸。
改这样:
detached DOM 节点多半是 style 没传导致虚拟滚动回收失效,或者你 item 里面有事件监听器没清理。