Table Virtualization Practices in React Ant Design: Approaches and Lessons
This article examines the challenges of virtualizing large Ant Design tables in a React+Umi stack, outlines three internal implementation strategies, discusses common pitfalls such as blank flicker and column fixing, and recommends open‑source alternatives for efficient table rendering.
Table and grid virtualization is not a new topic, yet the industry still lacks a one‑size‑fits‑all solution; this article walks through the team’s step‑by‑step exploration of virtualizing Ant Design’s Table component within a React+Umi stack, analyzing difficulties and possible resolutions.
The basic virtualization idea is to render only the elements that fall inside the visible viewport by calculating a startIndex and endIndex , determining the offset for the visible slice, and updating the DOM accordingly.
When Ant Design tables contain 1,000+ rows and 100+ columns, rendering can take around 5 seconds, which is unacceptable; therefore the goal is to keep the existing Table API while rendering only the viewport’s rows and columns and hiding the rest.
Ant Design v4 recommends integrating react-window via the components.body property. The following snippet shows the essential configuration:
...
// VariableSizeGrid is a component provided by react-window
const renderVirtualList = (rawData, { scrollbarSize, ref, onScroll }) =>
<VariableSizeGrid {...props} />
...
<Table
{...props}
className="virtual-table"
columns={mergedColumns}
pagination={false}
components={{ body: renderVirtualList }}
/>
...react-window is a lightweight library derived from react-virtualized , offering both list and grid virtualizers with a smaller bundle size.
However, the official solution suffers from feature regressions reported in GitHub issues #21022 and #20339, where row expansion, multi‑selection, and other Table functionalities are lost, and the Ant Design team advises users to implement their own fixes.
Internally, the Ant Design Table is built on top of rc-table , which abstracts data‑independent logic; the team examined this layer to decide whether to keep, modify, or replace it when adding virtualization.
Three internal proposals were evaluated:
Fork rc-table and add virtualization directly, sacrificing built‑in Ant Design features but keeping a lightweight core.
Intercept Ant Design’s scroll events, manually destroy off‑screen DOM nodes, and insert placeholders, preserving most Ant Design features with minimal code changes.
Re‑implement the table using react-table for data logic and react-window for virtualization, offering the most flexibility at the cost of higher development effort.
Key challenges identified include blank flicker during fast scrolling, variable row height handling, column‑fixing synchronization across multiple tables, and the lack of column virtualization; suggested mitigations involve increasing overscan, using refs for dynamic height measurement, syncing scroll positions, or avoiding excessive column counts.
For teams that prefer an out‑of‑the‑box solution, the article recommends open‑source alternatives such as rsuite-table and react‑base‑table , both of which provide built‑in virtualization and solid performance.
In conclusion, because table requirements vary widely across projects, the most effective approach is to tailor a virtualization strategy that fits the specific constraints, rather than relying on a single universal library.
ByteFE
Cutting‑edge tech, article sharing, and practical insights from the ByteDance frontend team.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.