Data Grid - Virtualization
The grid is high performing thanks to its rows and columns virtualization engine.
DOM virtualization is what makes it possible for the Data Grid to handle an unlimited* number of rows and columns. This is a built-in feature of the rendering engine and greatly improves rendering performance.
*unlimited: Browsers set a limit on the number of pixels a scroll container can host: 17.5 million pixels on Firefox, 33.5 million pixels on Chrome, Edge, and Safari. A reproduction.
Row virtualization
Row virtualization is the insertion and removal of rows as the Data Grid scrolls vertically.
The grid renders some additional rows above and below the visible rows. You can use rowBufferPx prop to hint to the Data Grid the area to render, but this value may not be respected in certain situations, for example during high-speed scrolling.
Row virtualization is limited to 100 rows in the Data Grid component.
Column virtualization
Column virtualization is the insertion and removal of columns as the Data Grid scrolls horizontally.
- Overscanning by at least one column lets the arrow key focus on the next (not yet visible) item.
- Overscanning slightly can reduce or prevent a flash of empty space when a user first starts scrolling.
- Overscanning more lets the built-in search feature of the browser find more matching cells.
- Overscanning too much can negatively impact performance.
By default, columns coming under 150 pixels region are rendered outside of the viewport. You can change this option with the columnBufferPx prop. As for rowBufferPx, the value may be ignored in some situations. The following demo renders 1,000 columns in total:
You can disable column virtualization by calling apiRef.current.unstable_setColumnVirtualization(false), or by setting the columnBufferPx to a high value.
Scrolling without render gaps
The virtualizer supports two layout modes that differ in how scrolling and row positioning work:
Uncontrolled mode (default). The rows' positions are set relative to the native scroll container. A JavaScript logic updates the virtualized rows asynchronously to cover the current scroll position.
(For example, the data grid uses CSSstickypositioning to keep headers and pinned rows in place, rendered rows are positioned inside a filler element that stretches the scroll container to the correct total height.)
The downsides:- During fast scrolling, the native scroll update can outpace the JavaScript rendering logic, which produces brief empty row areas.
Controlled mode. The rows' positions are set in absolute. A JavaScript logic updates the virtualized rows asynchronously to cover the current scroll position. Headers, pinned rows, and data rows always move as one unit.
The downsides:- During fast scrolling, depending on the browser, the JavaScript rendering logic can be slower than what the native scroll would be, leading to a feeling of lag.
- Safari row position update is capped at 60Hz, even on higher refresh-rate displays, because of
requestAnimationFrames(): webkit#173434.
Use the virtualizerLayoutMode key inside experimentalFeatures to opt in to the controlled mode:
<DataGrid experimentalFeatures={{ virtualizerLayoutMode: 'controlled' }} />
The demo below lets you switch between modes and scroll quickly to see the difference. If you don't see the difference, consider setting CPU Throttling in Chrome Dev Tools to simulate a lower-end device.
Layout mode:
Disable virtualization
The virtualization can be disabled completely using the disableVirtualization prop.
You may want to turn it off to be able to test the Data Grid with a headless browser, like jsdom.
<DataGrid {...data} disableVirtualization />