长列表滚动卡顿,怎么优化内存占用?

UX-艳玲 阅读 18

我用 React 渲染一个上千条消息的聊天列表,虽然用了虚拟滚动,但内存还是涨得特别快,页面越滚越卡。是不是没清理掉不可见的 DOM 节点?

目前是用 react-windowFixedSizeList,每个 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>
我来解答 赞 2 收藏
二维码
手机扫码查看
1 条解答
Designer°国娟
我之前也遇到过这个问题,你这代码漏了关键的 style 属性传递,react-window 必须把 style 传给 item 组件才能正确回收 DOM。

另外 itemData 如果每次渲染都是新数组引用,会导致所有 item 重渲染,内存肯定炸。

改这样:

const MessageItem = React.memo(({ data, index, style }) => {
const message = data[index];
return (

{message.text}

);
});

// 用 useMemo 包住 messages 避免每次新引用
const memoizedMessages = useMemo(() => messages, [messages]);

height={600}
itemCount={memoizedMessages.length}
itemSize={60}
itemData={memoizedMessages}
>
{MessageItem}


detached DOM 节点多半是 style 没传导致虚拟滚动回收失效,或者你 item 里面有事件监听器没清理。
点赞
2026-03-02 14:01