react渲染长列表引发的性能问题?

起因

页面
问题的起因是左侧模版列表在开发时没有测试最多五百条数据的极限,当数据列表达到五百条的时候,就单纯的改变checkbox组件状态(选中或者不选中之间切换),就很慢,看了一下性能分析,一个click事件在4倍降低CPU的情况下长达4s的长任务,我不理解 :)

放大图

这里我在控制台中,发现列表并没有重新渲染所有节点,而且也没有接口调用。仅仅五百个节点就这样,虚拟dom性能有点...

顺便补充一下:react版本是18.2.0,组件库是"antd": "^4.21.0"。难道Fiber树对于虚拟dom树没有提升,还是我使用方式不对?
组件书写结构大概是这样:

const GroupItem = (props: GroupItemProps) => {
   .....
}

const TpTemplate = () => {
   return 
          <>{
             <CheckboxGroup
              className="group-check"
              value={checkedList}
              onChange={onChange}
              style={{ width: '100%' }}
            >
              {TpTemplateList?.map(group => (
                <div className="group-container" key={group?.id}>
                  <Checkbox value={group.id} className="group-check" />
                  <GroupItem
                   {...props}
                  >
                    {group.name}
                  </GroupItem>
                </div>
              ))}
              {!(TpTemplateList?.length > 0) && <Empty />}
            </CheckboxGroup>
          }</>
}

并不一定要提出解决问题的方案,我就想知道,500个节点就卡成这样吗?event loop的时间到底消费到哪里了?

有大佬解惑吗?万分感谢!

这里我补充了一个在线代码demo:简易代码demo
主要问题原因还是在于react框架本身的问题,props改变组件重新渲染
先把问题放在这里吧,后面有答案了我会贴出来。

阅读 2.6k
1 个回答

GroupItem用React.memo:

const GroupItem = React.memo((props: GroupItemProps) => {
  // ...
});

第三方库:

import { FixedSizeList as List } from 'react-window';

const TpTemplate = () => {
  // ...

  return (
    <List
      height={500} // 视窗的高度
      itemCount={TpTemplateList?.length || 0}
      itemSize={50} // 每个列表项的高度
    >
      {({ index, style }) => {
        const group = TpTemplateList[index];
        return (
          <div style={style} key={group?.id}>
            <Checkbox value={group.id} className="group-check" />
            <GroupItem {...props}>{group.name}</GroupItem>
          </div>
        );
      }}
    </List>
  );
};
撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题