Use client virtualization for a browser-owned working set
Load the records once when payload size, memory, client sorting, and client filtering remain acceptable. Virtualization bounds DOM work but the browser still stores and processes the dataset.
Use infinite loading for sequential discovery
Infinite loading suits feeds or search results where users append pages and do not need a complete global sort, group, or pivot over unloaded records. Define cursors, duplicate prevention, retry, and end-of-data behavior.
Use server row model for remote operations
Choose Enterprise when the server must own filtering, sorting, grouping, pivoting, or paging. Define request fields, stable ordering, total-row semantics, block cache, cancellation, retries, edits, invalidation, and authorization before UI work.
Choose where global truth lives
A large data grid decision starts with ownership. If the browser owns the full working set, Core virtualization may be enough. If users discover records sequentially, infinite loading may be enough. If the server owns global filtering, sorting, grouping, paging, or permissions, Enterprise server row model behavior becomes relevant. This ownership framing is more useful than discussing row count alone.
Define row identity across pages
Stable row IDs must survive pagination, cursor loading, sorting, filtering, refresh, and edits. Duplicate or shifting IDs break selection, dirty state, focus, and audit trails. This is a practical requirement for any large data grid in React and should be repeated because it is more important than raw row count.
Define bulk action and export scope
Specify whether selection means visible rows, loaded rows, explicit IDs, or every record matching a server-side filter. Display that scope to users. Global export and bulk action require a backend query, authorization, size limits, progress, cancellation, and audit records because the browser cannot safely act on records it never loaded.
Product evidence
Server row model
Ace Grid Enterprise includes server row model normalization and request helpers in addition to Core virtualization.
Large data grid React implementation
import { Grid } from "@ace-grid/enterprise";
export function ServerBackedGrid({ rows, columns }) {
return (
<Grid
data={{ rows, columns }}
layout={{ width: 1200, height: 620 }}
columns={{ columnWidths: {} }}
serverRowModel={{
enabled: true,
blockSize: 200,
getRows: ({ startRow, endRow, sortModel, filterModel }) =>
fetchAccountRows({ startRow, endRow, sortModel, filterModel }),
}}
charts={{ enabled: true }}
pivot={{ enabled: true }}
masterDetail={{ enabled: true }}
/>
);
}
Choose a large-data strategy
Limitations and tradeoffs
- Do not build a remote row model when the complete working set is small, stable, and inexpensive to load into the browser.
- Do not confuse a slow custom renderer with a data-loading problem; profile rendering and queries separately.
Common questions
When should sorting and filtering move to the server?
Move them when the browser does not own the complete authoritative set or when permissions, grouping, totals, or query cost require backend evaluation.
Can infinite loading provide global selection and export?
Only if the application defines those operations against server-side query identity. Loaded rows alone do not represent the full result set.