当前位置: 首页 > 知识库问答 >
问题:

react.js - AntD Table中rowClassName执行多次导致性能问题,如何解决?

魏安然
2024-07-22

AntD,Table用rowClassName控制行的背景色,包括选中行的背景色,选中行的index在onClick方法设置到useState。数据很多的情况下,tableRowClassName方法会执行多次,导致选择行时很慢

<Table dataSource={dataSource} columns={columns} size="small" bordered 
        loading={viewForm.loading} pagination={false} rowClassName={tableRowClassName} scroll={{ x: 1300, y: maxHeight}}
        onRow={(record, rowIndex) => ({
          onClick: () => onRowClick(record, rowIndex),
          onDoubleClick: () => getoPage(2, rowData),
        })}/>

const tableRowClassName = (record: any, index: number) => {
    console.info("tableRowClassName");
    if (viewForm.rowIndex === index) {
      return 'selected-row';
    }
    if (index % 2 === 1) {
      return 'light-blue-background';
    }
    
    if (record.StpKbn == 1) {
      return ' stop-distinguish-row';
    }
    if (record.SaihenCoNamUpdKbn == 1) {
      return ' disabled-distinguish-row';
    }
    return "";
  }

有什么方法在选择行时,变快一点吗?

共有1个答案

东方宜
2024-07-22

在Ant Design的Table组件中,rowClassName函数会在每次渲染时针对每一行被调用,这确实可能导致性能问题,尤其是在处理大量数据时。为了优化性能,你可以考虑以下几种方法:

  1. 使用Memoization(记忆化):
    你可以使用React的useMemo或者一个第三方库(如reselect)来缓存rowClassName的结果。但是,由于rowClassName是一个基于props和当前行的函数,因此它的参数(如indexrecord)可能会在每次渲染时变化,这限制了memoization的有效性。尽管如此,如果viewForm.rowIndexdataSource没有频繁变化,记忆化仍然可能有所帮助。
  2. 减少不必要的渲染:
    确保你的组件树在不需要时不会重新渲染。使用React.memouseCallbackuseMemoPureComponent(如果你使用的是类组件)可以帮助减少不必要的渲染。
  3. 优化rowClassName函数:
    你的rowClassName函数目前检查了多个条件。如果可能的话,考虑简化逻辑或使用更快的替代方法。例如,如果你可以预计算每行的类名,并将其作为数据的一部分传递给Table,那么这将避免在每次渲染时重新计算。
  4. 使用CSS代替JS逻辑:
    如果可能的话,考虑使用CSS而不是JavaScript来处理行的样式。例如,你可以使用CSS的:nth-child选择器来处理奇偶行的背景色,而不需要在JavaScript中检查index
  5. 分页:
    如果你的表有很多行,考虑使用分页来减少一次渲染中显示的行数。这将直接减少rowClassName函数被调用的次数。
  6. 使用虚拟滚动:
    对于非常大的数据集,虚拟滚动(也称为窗口化)是一个有效的性能优化技术。它只渲染视口中可见的行,而不是整个数据集。这可以显著减少rowClassName的调用次数和DOM节点的数量。
  7. 检查其他性能瓶颈:
    确保性能问题不是由其他因素引起的,如复杂的列渲染器、大型单元格内容或昂贵的onRow事件处理程序。

在你的具体情况下,由于你需要在onClick事件中更新viewForm.rowIndex,这可能会触发整个表的重新渲染。为了优化这一点,你可以考虑使用React的useStateuseCallback来确保onRowClicktableRowClassName只在依赖项变化时更新。但是,请注意,由于indexrecord对于每一行都是唯一的,所以完全避免重新渲染可能是不现实的。

以下是一个使用useCallback的示例,但请注意,它可能不会完全解决性能问题,因为它仍然需要在每次渲染时调用tableRowClassName

const [viewForm, setViewForm] = useState({ rowIndex: null, /* ...其他状态... */ });

const onRowClick = useCallback((record, rowIndex) => {
  setViewForm(prevState => ({ ...prevState, rowIndex }));
}, []);

const tableRowClassName = useCallback((record: any, index: number) => {
  // ... 你的逻辑 ...
}, [viewForm.rowIndex]); // 注意这里只依赖于viewForm.rowIndex,但可能不足以避免所有重新渲染

// ... 你的Table组件 ...
 类似资料:
  • 大部分软件都可以通过付出相对较小的努力,让他们比刚发布时快上10到100倍。在市场的压力下,选择一个简单而快速的解决问题的方法是比选择其它方法更为明智而有效率的选择。然而,性能是可用性的一部分,而且通常它也需要被更仔细地考虑。 提高一个非常复杂的系统的性能的关键是,充分分析它,来发现其“瓶颈”,或者其资源耗费的地方。优化一个只占用1%执行时间的函数是没有多大意义的。一个简要的原则是,你在做任何事情

  • 学习理解运行的程序的性能问题与学习 debug 是一样不可避免的。即使你完美、精确地理解了你的代码运行时所产生的开销,你的代码也会调用其他你几乎不能控制的或者几乎不可看透的软件系统。然而,实际上,通常性能问题和调试有点不一样,而且往往要更简单些。 假如你或你的客户认为你的一个系统或子系统运行太慢了。在你把它变快之前,你必须构建一个它为什么慢的思维模型。为了做到这个,你可以使用一个图表工具或者一个好

  • 我是Java开发新手,不熟悉各种导入(Maven、Git等),所以我简单地说: 这两个没有在代码中解决我正在检查,我不知道我应该采取什么样的行动,也不知道我应该导入什么来解决它,但它可能是一些流行的库。 是否有完整的指南指导开发人员如何在eclipse中导入包(例如,C#开发人员使用Nuget,尽管有大量手工制作的包),或者他们真的使用所有这些巨大的导入选择器?

  • 问题内容: 在Ruby中,我没有重复很多次“ require”(在Python中为“ import”)一词,而是 因此,它将遍历每个“ lib”和“ require”(导入)的集合。现在,我正在编写Python脚本,我想做类似的事情。是否有办法为所有这些人写“导入”。 简单的“引导”将类似于以下代码。无论如何,由于Python不会导入命名为字符串的库,因此它不起作用。 提前致谢 问题答案: 对于已

  • 你好想问一下,刚刚接触react,之前写的js在html上可以使用,但是换到这里显示document is not defined,如果在document.getElementById不能用的情况下还有什么办法能够通过id获取到元素?或者应该怎么修改才能正常获取呢?写的屎山如下,请大佬指教qaq 1

  • 问题内容: 我正在使用Pybossa Webhooks,并找到了此插件来实时分析Pybossa结果。我分叉了它,但没有得到如何执行。 目前,我正在执行以下操作: python app.py test_project 其中test_project是我的project_short_name。但是,它使我恢复到此存储库的index.html页面。 问题答案: 我找到了 !查看您将找到的功能,它将webh