react-virtualized Table渲染性能差、滚动点击后卡顿如何优化?
React Virtualized Table 性能优化方案
一、现有代码的核心问题
当前卡顿的核心原因是大量不必要的重渲染:所有渲染函数内的回调、配置对象都是内联生成的,每次父组件更新都会生成新的引用,触发Table、Column组件递归重渲染,滚动时频繁更新的状态会进一步放大这个问题。
二、基础优化(无需修改渲染逻辑)
先完成以下优化,90%的场景下可以解决卡顿问题:
- 所有回调函数用
useCallback做引用固化,避免每次渲染生成新函数// 组件内部提前封装所有回调 const headerRenderer = useCallback(({dataKey}) => headersConfig[dataKey].content, [headersConfig]) const cellRenderer = useCallback(({ cellData }) => cellData, []) const rowGetter = useCallback(({ index }) => getRowRow(index), [getRowRow]) const rowClassName = useCallback(getRowClassName, [getRowClassName]) const noRowsRenderer = useCallback(noRowsRendererHandler, [noRowsRendererHandler]) - 所有配置对象、渲染数组用
useMemo固化引用// 列配置固化 const headersConfig = useMemo(() => ({ // 你的列配置逻辑 }), [/* 仅填写配置依赖的可变变量 */]) // 表格列组件提前生成,避免每次渲染重绘 const tableColumns = useMemo(() => { return Object.keys(headersConfig).map((key) => ( <Column key={key} headerRenderer={headerRenderer} cellRenderer={cellRenderer} dataKey={key} width={headersConfig[key].width} /> )) }, [headersConfig, headerRenderer, cellRenderer]) // 行数据如果是加工生成的也需要固化 const tableRowsData = useMemo(() => rawData.map(/* 数据加工逻辑 */), [rawData]) - 表格单元格内的自定义子组件全部用
React.memo包裹,仅当props变化时才更新 - 调整
overscanRowCount属性,默认值为10,可调低到3-5,减少滚动时预渲染的行数量,避免不必要的渲染开销
三、rowRenderer使用场景与实现示例
如果完成上述优化后滚动卡顿仍然存在,说明行内渲染逻辑过重,默认的Column嵌套层级太高,可以用rowRenderer自定义整行渲染,减少组件嵌套开销。
实现示例:
const rowRenderer = useCallback(({ key, index, style, isScrolling, }) => { // 滚动过程中可渲染简化占位符,进一步提升滚动流畅度 if (isScrolling) { return <div key={key} style={style} className="row-placeholder">加载中</div> } const rowData = getRowRow(index) const rowClass = getRowClassName({index}) return ( <div key={key} style={style} className={rowClass}> {/* 直接渲染所有列,跳过Column组件的额外嵌套层级 */} {Object.keys(headersConfig).map(colKey => ( <div key={colKey} style={{width: headersConfig[colKey].width, display: 'inline-block'}} > {rowData[colKey]} </div> ))} </div> ) }, [getRowRow, getRowClassName, headersConfig]) // 传入Table组件后不需要再写Column子组件 <Table {/* 原有其他属性保持不变 */} rowRenderer={rowRenderer} > </Table>
内容的提问来源于stack exchange,提问作者dush
相关产品推荐
相关产品推荐

