当使用 Ant Design 3.x 的 Table 组件处理海量数据时,确实会遇到性能卡顿问题。以下是针对此问题的优化方案:
import { Table } from 'antd';
import { VariableSizeList as List } from 'react-window';
const VirtualTable = (props) => {
const { columns, scroll } = props;
const [tableWidth, setTableWidth] = React.useState(0);
const widthColumnCount = columns.filter(({ width }) => !width).length;
const mergedColumns = columns.map((column) => {
if (column.width) {
return column;
}
return {
...column,
width: Math.floor(tableWidth / widthColumnCount),
};
});
const renderVirtualList = (rawData, { scrollbarSize, ref, onScroll }) => {
const rowHeight = 54; // 根据实际情况调整
return (
<List
height={scroll.y}
itemCount={rawData.length}
itemSize={() => rowHeight}
onScroll={onScroll}
ref={ref}
width="100%"
>
{({ index, style }) => {
const record = rawData[index];
return (
<div style={style}>
{/* 渲染单行数据 */}
</div>
);
}}
</List>
);
};
return (
<Table
{...props}
className="virtual-table"
columns={mergedColumns}
pagination={false}
components={{
body: renderVirtualList,
}}
/>
);
};
const [data, setData] = useState([]);
const [loading, setLoading] = useState(false);
const [pagination, setPagination] = useState({
current: 1,
pageSize: 50,
});
const fetchData = async (params = {}) => {
setLoading(true);
try {
const { current, pageSize } = params.pagination || pagination;
const response = await fetchDataFromAPI(current, pageSize);
setData(response.data);
setPagination({
...params.pagination,
total: response.total,
});
} finally {
setLoading(false);
}
};
useEffect(() => {
fetchData();
}, []);
const handleTableChange = (newPagination) => {
fetchData({
pagination: newPagination,
});
};
<Table
columns={columns}
dataSource={data}
pagination={pagination}
loading={loading}
onChange={handleTableChange}
/>
// 使用React.memo优化列组件
const MemoizedColumn = React.memo(({ text }) => (
<span>{text}</span>
));
const columns = [
{
title: 'Name',
dataIndex: 'name',
render: (text) => <MemoizedColumn text={text} />,
},
// 其他列...
];
// 避免在dataSource中使用复杂嵌套对象
const optimizedData = rawData.map(item => ({
id: item.id,
name: item.name,
// 只保留表格需要展示的字段
}));
// 使用window.requestIdleCallback延迟非关键渲染
const renderExpandedRow = (record) => {
requestIdleCallback(() => {
// 渲染复杂内容
});
return <div>Loading details...</div>;
};
<Table
dataSource={data}
columns={columns}
rowSelection={null} // 不需要选择功能时禁用
expandable={null} // 不需要展开功能时禁用
/>
console.time('table-render');
// 渲染表格
console.timeEnd('table-render');
如果可能,考虑升级到Ant Design 4.x或5.x,新版对大数据量表格有更好的内置优化。
以上方案可根据实际业务场景组合使用,通常虚拟滚动和分页加载能带来最显著的性能提升。