React grid virtualization

React data grid virtualization for large tables

Virtualization is the difference between rendering a usable viewport and asking React to mount an entire dataset. Ace Grid treats virtualization as part of the grid surface, not a decorative performance toggle.

Open virtualization documentation Choose a data strategy

Understand the rendering model

Without virtualization, the browser may create DOM for every visible and offscreen row and cell. Style calculation, layout, paint, memory, and React reconciliation grow with that rendered surface. Row virtualization renders a moving vertical window; horizontal virtualization limits columns in wide grids; cell-content virtualization can defer expensive inner content. These techniques preserve a large logical dataset while keeping the mounted interface closer to the viewport.

Configure Ace Grid virtualization deliberately

Ace Grid exposes enableVirtualization, enableHorizontalVirtualization, enableCellContentVirtualization, rowBufferPx, and columnBufferPx through the virtual prop group. Start with row virtualization for tall datasets, add horizontal virtualization for many wide columns, and use content virtualization only when cell bodies are measurably expensive. Keep the default buffers until profiling shows blank work or excessive mounted DOM, then change one buffer at a time. Give the grid a bounded height and stable dimensions so performance improvements and interaction regressions can be attributed correctly.

Use stable row identity

Virtualized DOM is reused as the viewport moves, so record identity cannot depend on visual position. Every row needs a stable ID that survives sorting, filtering, loading, and updates. Test editing and selection while rapidly scrolling, then return to the same record and confirm state is attached to the row rather than the recycled element. Unstable IDs can produce edits, focus, or selection on the wrong business record.

Plan row height and overscan

Predictable row height makes scroll offsets and viewport calculations reliable. Variable heights require measurement and can cause jumps when content changes. Overscan renders a buffer beyond the visible area to avoid blank edges during fast movement, but excessive overscan recreates much of the DOM cost virtualization should remove. Test trackpad, mouse wheel, scrollbar drag, Page Down, keyboard navigation, and programmatic scrolling on target hardware.

Separate virtualization from infinite loading

Virtualization controls rendering; infinite loading controls when additional rows are requested. Ace Grid scroll props support host-driven loading with batch size, threshold, direction, offset, page, or cursor strategies. The grid requests data, but the application updates the row source. Define duplicate prevention, cursor advancement, retry, end-of-data, and selection behavior across loaded windows. A fast viewport cannot compensate for an unreliable loading contract.

Define a performance budget

Set measurable thresholds for the target devices: time to first usable interaction, maximum edit-start delay, acceptable filter response, scroll blanking, long-task duration, and memory growth. Budgets make regressions visible in CI or release testing. Use representative data generators and custom renderers so tests remain repeatable. A performance claim without hardware, workload, and measurements is not useful evidence.

Product evidence

Three virtualization controls

GridVirtualProps exposes row, horizontal-column, and cell-content virtualization flags plus rowBufferPx and columnBufferPx for measured overscan tuning.

Infinite loading is a separate concern

GridScrollProps includes loadMoreRows plus batch-size, threshold, direction, offset, and cursor options. Virtualization limits rendered DOM; it does not fetch remote data by itself.

Live Ace Grid example

Virtualized viewport preview

Visible row windows, load states, render health, and scroll actions for large-grid evaluation.

Visible rowViewportLoad stateCellsRenderAction
Row 12,480VisibleLive98092%Render
Row 12,481VisibleLive87089%Scroll
Row 12,482PrefetchReview33073%Load
Row 12,483PendingEscalate21058%Fetch

Virtualized Ace Grid example

import { Grid } from "@ace-grid/core";

export function VirtualizedOrdersGrid({ rows, columns, loadMoreRows }) {
  return (
    <Grid
      data={{ rows, columns }}
      columns={{ columnWidths: {}, fillWidth: true }}
      layout={{ width: 1200, height: 600 }}
      virtual={{
        enableVirtualization: true,
        enableHorizontalVirtualization: true,
        enableCellContentVirtualization: true,
      }}
      scroll={{
        enableInfiniteScroll: true,
        infiniteScrollBatchSize: 100,
        loadMoreRows,
      }}
    />
  );
}

Rendering and data-loading strategies

Strategy What it solves What it does not solve
Row virtualization Bounds mounted row elements Does not reduce local data-processing cost
Horizontal virtualization Bounds cells in very wide grids Adds focus and measurement cases to test
Infinite loading Fetches additional rows near a scroll boundary Separate from viewport rendering
Server row model Moves sort, filter, grouping, and paging to a remote data source Requires Enterprise and a reliable request contract

Limitations and tradeoffs

  • Do not add virtualization to a small grid when the extra rendering boundary provides no measured benefit.
  • Virtualization does not fix slow server queries, expensive data transforms, or unstable row identity.

Common questions

How large must a grid be before virtualization helps?

There is no universal row threshold. Measure mounted cells, render cost, interaction latency, and memory with the real columns and custom renderers.

Is virtualization the same as server-side loading?

No. Virtualization limits mounted UI. Infinite loading or the server row model separately controls which records are fetched.

Sources