How We Built a High‑Performance React Data Grid with AntV S2
This article details how Ant Financial’s front‑end team created a fast, extensible React big‑data table component using the open‑source AntV S2 Canvas library, covering performance‑driven technical choices, custom cell editing, virtual scrolling, freezing, filtering, sorting, and integration challenges that replaced costly commercial spreadsheet solutions.
Introduction
In Ant Financial’s big‑data R&D platform, a data table component is needed to display tens of thousands of SQL query results with features such as filtering, sorting, searching, copying, selection, and editing. Commercial spreadsheet solutions were too expensive and hard to customize, so the team built a JavaScript‑based spreadsheet using the open‑source Canvas rendering library AntV S2.
Business Scenario
Dataphin, Ant’s internal big‑data platform, provides end‑to‑end data lifecycle capabilities. Its data tables are used throughout, especially for displaying computation task results. The component must support both read‑only preview of large result sets and manual data entry.
Technical Choice – Why AntV S2?
Canvas‑based rendering offers higher performance than DOM for complex, interactive tables. The DOM rendering pipeline involves data structure construction, style parsing, layout calculation, and finally painting, which becomes a bottleneck for large data. Canvas directly maps to low‑level 2D graphics APIs, eliminating layout overhead and allowing arbitrary drawing, making it ideal for high‑performance, large‑data scenarios.
Market Comparison
The team evaluated existing Excel‑like front‑end table components:
SpreadJS – powerful but expensive and poor performance on large data.
LuckySheet / x‑spreadsheet – open‑source but community‑maintained with limited stability.
Handsontable – DOM‑based and commercial.
Various SaaS table services – provided as SDKs, not pure front‑end components.
Finding no suitable option, Ant’s front‑end team decided to open‑source their own cross‑table component based on AntV S2.
AntV S2 Overview
S2 is a data‑visualisation engine that delivers high‑performance, extensible, and beautiful multi‑dimensional tables. It supports both pivot‑table and detail‑table modes, offering rich interaction capabilities.
Key Feature Implementations
Cell Editing
Editing is essential for data entry. Since S2 focuses on analysis, cell editing is not built‑in and must be added. The team chose a DOM overlay for editing because browsers handle cursor rendering, text selection, and line breaks efficiently.
const EditableMask = () => {
const { left, top, width, height } = useMemo(() => {
const rect = (spreadsheet?.container.cfg.container as HTMLElement).getBoundingClientRect();
return {
left: window.scrollX + rect.left,
top: window.scrollY + rect.top,
width: rect.width,
height: rect.height,
};
}, [spreadsheet?.container.cfg.container]);
return (
<div className="editable-mask" style={{
zIndex: 500,
position: 'absolute',
left,
top,
width,
height,
}}/>
);
};The editing flow:
Calculate the DOM mask size and position to match the Canvas.
Listen for DATA_CELL_DOUBLE_CLICK and render a textarea at the cell’s coordinates using the cell’s x/y/width/height/value and the current scroll offset.
On blur or Enter, destroy the textarea, write the new value back to spreadsheet.originData, and emit an event.
Brush Selection
Brush selection lets users drag to select multiple cells, with auto‑scroll when the cursor leaves the canvas. The implementation tracks StartBrushPoint , EndBrushPoint , and BrushRange , computes the direction (leading/trailing on X/Y), and triggers scrolling with variable speed based on distance from the canvas edge.
const MAX_SCROLL_DURATION = 300;
const MIN_SCROLL_DURATION = 16;
let ratio = 3;
if (config.x.scroll) {
ratio = 1;
}
this.spreadsheet.facet.scrollWithAnimation(
offsetCfg,
Math.max(MIN_SCROLL_DURATION, MAX_SCROLL_DURATION - this.mouseMoveDistanceFromCanvas * ratio),
this.onScrollAnimationComplete,
);Virtual Scrolling
To render only visible cells, the component calculates the viewport index range [xMin, xMax, yMin, yMax], diffs it against the previous range, and adds or removes cells accordingly. This keeps rendering time proportional to the viewport size rather than the total data size.
export const diffPanelIndexes = (sourceIndexes, targetIndexes) => {
const allAdd = [];
const allRemove = [];
Object.keys(targetIndexes).forEach(key => {
const { add, remove } = diffIndexes(sourceIndexes?.[key] || [], targetIndexes[key]);
allAdd.push(...add);
allRemove.push(...remove);
});
return { add: allAdd, remove: allRemove };
};Custom Column Header
S2 allows custom cell classes. By extending TableDataCell or TableCornerCell, developers can draw custom icons, implement resize handles, and render Excel‑like triangular corner indicators.
import { TableDataCell } from '@antv/s2';
class S2Cell extends TableDataCell {
private drawActionIcon() {
// custom drawing logic using AntV/G API
}
}
export default S2Cell;Row/Column Freezing
Freezing is achieved by grouping cells into frozenRowGroup, frozenColGroup, frozenTrailingRowGroup, frozenTrailingColGroup, and a normal panelScrollGroup. During translation, frozen groups move only along one axis, while the scroll group moves freely.
Toolbar Operations
Filtering & Sorting – Implemented via S2’s DataCfg.filterParams and DataCfg.sortParams. Value filtering supports multi‑level linkage and virtualized checkbox lists to avoid UI lag.
Search – Finds matching cells, focuses them, and scrolls them into view using facet.scrollWithAnimation.
Column Visibility – Controlled by updating dataCfg.fields.columns based on a hidden‑column list.
Copy to Clipboard – Uses navigator.clipboard when available, falling back to document.execCommand('copy') for large data sets.
export const copyToClipboard = (str, sync = false) => {
if (!navigator.clipboard || sync) {
return copyToClipboardByExecCommand(str);
}
return navigator.clipboard.writeText(str).catch(() => copyToClipboardByExecCommand(str));
};Performance Results
Compared with the previous SpreadJS implementation, the new S2‑based component reduces tab‑switch time from ~500 ms to 80 ms (6× faster) and renders 50 k rows in about 1 s (8× faster). The open‑source nature also simplifies debugging and future feature extensions.
Conclusion
By leveraging AntV S2, the team built a highly extensible, performant React big‑data table that replaces costly commercial products, supports full UI customization, and opens the path for future enhancements such as advanced cell editing, aggregation, and multi‑level headers.
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
Alipay Experience Technology
Exploring ultimate user experience and best engineering practices
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.
