Handling Large Datasets in Ant Design: Table vs. Virtualization
Deciding between standard Ant Design Tables, pagination, and virtualization for large datasets. Learn how to avoid DOM bloat and implement virtual lists for high-performance data grids.
13 Sept 2026, 14:58 UTC

The DOM Bloat Problem
When rendering thousands of rows in a standard Ant Design Table, the browser must maintain every single DOM node for every cell in the dataset. This leads to "DOM bloat," where memory usage spikes and the UI becomes unresponsive during scrolling or sorting. The core decision is whether to manage this via pagination, a standard table, or a virtualized list.
Choosing the Right Rendering Strategy
The following table compares the three primary methods for handling data volume in Ant Design (assuming v5.x). Each approach shifts the performance bottleneck to a different area.
| Feature | Standard Table | Pagination | Virtualization |
|---|---|---|---|
| DOM Complexity | O(n) - Linear to data size | O(k) - Constant per page | O(v) - Constant per viewport |
| Initial Load | Slow (renders all) | Fast (renders subset) | Fast (renders visible) |
| UX Pattern | Single long list | Page-by-page navigation | Infinite smooth scroll |
| Constraint | Browser memory limits | User friction (clicking pages) | Requires fixed row height |
Trade-offs and Engineering Constraints
Standard Table: Best for datasets under 100 rows. It provides the most seamless integration with Ant Design's built-in sorting, filtering, and row selection without additional configuration.
Pagination: The safest architectural choice for extremely large datasets (10,000+ rows) because it allows for server-side slicing. This prevents the client from ever receiving the full payload, reducing network overhead.
Virtualization: Ideal for "power user" interfaces where users need to scan thousands of rows quickly without clicking through pages. However, virtualization introduces specific technical risks:
- Fixed Heights: Virtual lists calculate the scroll position based on
rowHeight * index. If your rows have dynamic heights (e.g., wrapping text), the scrollbar will jump or rows will overlap. - CSS Selectors: CSS rules relying on
:nth-childor total child counts will fail because the DOM only contains the visible slice. - Component Flicker: Complex components (like
SelectorDatePicker) inside virtual cells may flicker or lose state during rapid scrolling as they are unmounted and remounted instantly.
Implementing a Virtualized Table
Since Ant Design's standard Table does not include a built-in virtual prop, the industry standard is to integrate react-window or react-virtualized. Below is the configuration logic for implementing a virtualized body while keeping the Ant Design header.
// Required: npm install react-window
import React from 'react';
import { Table } from 'antd';
import { FixedSizeList as List } from 'react-window';
const VirtualTable = ({ data }) => {
const renderRow = ({ index, style }) => {
const record = data[index];
// We manually render the row content to avoid the standard Table body loop
return (
<div style={{ ...style, display: 'flex', borderBottom: '1px solid #f0f0f0' }}>
<div style={{ width: 100 }}>{record.id}</div>
<div style={{ flex: 1 }}>{record.name}</div>
<div style={{ width: 100 }}>{record.status}</div>
</div>
);
};
return (
<Table
columns={[
{ title: 'ID', dataIndex: 'id', width: 100 },
{ title: 'Name', dataIndex: 'name' },
{ title: 'Status', dataIndex: 'status', width: 100 },
]}
dataSource={data}
pagination={false}
components={{
body: (props) => (
<List
height={500} // Viewport height
itemCount={data.length}
itemSize={54} // Fixed row height in pixels
width={'100%'}
>
{renderRow}
</List>
),
}}
/>
);
};
Verification and Diagnostics
To ensure the virtualization is functioning and not simply hiding elements with CSS, perform these checks:
- DOM Inspection: Open Browser DevTools (F12). Inspect the
<tbody>or the virtual list container. Scroll rapidly; you should see the number of<div>or<tr>elements remain constant (e.g., always 15-20 elements) regardless of whether the dataset has 100 or 10,000 items. - TTI Metric: Use the Lighthouse tab in Chrome. Compare a standard table with 2,000 rows against the virtualized version. The virtualized version should show a significantly lower "Time to Interactive" (TTI) because the browser is not parsing a massive DOM tree on load.
- Logic Validation: Trigger a sort or filter. Ensure the data array is updated before being passed to the
Listcomponent to prevent the virtual index from pointing to the wrong record.
Limitations
Virtualization is not a universal fix. If your application requires column resizing or complex row spanning (rowspan/colspan), virtualization becomes exponentially harder to implement as it breaks the standard table layout engine. In those cases, server-side pagination is the only stable alternative.
0 replies
A thoughtful contribution can make all the difference. Be the first to share one.