Performance
100,000 rows, instant rendering, zero blank cells while scrolling.
The demo below renders 100,000 rows × 5 columns instantly. Scroll it, fling the scrollbar, or hold Shift+ArrowDown.
Scroll through the 100,000 rows and watch the FPS counter (top-left) — only the visible rows are ever mounted.
Limits
Comfort target vs. hard ceiling
The comfort target is 100k rows. The hard ceiling is ~1M, a Chromium CSS Grid track limit, not a gridcn limit.
Keeping it fast
gridcn windows rows by scroll velocity. The scroll surface uses CSS transforms, so the browser never reveals an unrendered area. A one-row scroll step re-renders only the cells of the entering row. A jump farther than the viewport plus the velocity buffer mounts only the base overscan. See Virtualization for the row and column virtualization model.
Row hover is an attribute on the hovered row. It does not use a :hover rule or a transition. The
attribute stays on its row while the grid scrolls, so scrolling causes no style recalculation for
hover. The grid reads the row under the pointer again when the scroll settles and after the view
changes. Marker cells re-render only when their own props or the selection state of their row change.
In our headless test on 100,000 rows, a sequence of jumps had a median longest frame of 16.8 ms, down from 91.7 ms. The number of frames over 33 ms fell from 4 to 0. These numbers come from the regression suite in this repository. Your hardware and cells change them.
Keep data/columns references stable
A dev-mode guardrail shows a warning when a reference is not stable. Also keep scroll-visible custom cells simple. Editors mount only for the single editing cell, so complex edit-mode logic has no cost while you scroll.
Keep getRowClassName/getCellClassName identity stable too
A new function literal on every render breaks row and cell memoization for the whole grid. A dev build shows this warning:
[data-grid] getRowClassName identity changed since the last render; pass a stable reference (e.g. useCallback) or every row re-renders
[data-grid] getCellClassName identity changed since the last render; pass a stable reference (e.g. useCallback) or every cell re-rendersTo fix this, move the function to module scope, or wrap it in useCallback with a stable
dependency list.
Verified by a regression suite
A real-Chromium regression suite enforces every guarantee above. The suite checks for blank areas under randomized scrollbar-drag deltas, an FPS regression gate, and a wasted-render probe.
Run the benchmarks yourself
See the Benchmarking section in the repository's DEVELOPMENT.md.
Is your dataset too large to load, not just too large to render?
Virtualization solves rendering. Everything above is about scroll performance once the data exists on the client. If you cannot fetch the whole dataset up front, see Lazy loading to fetch row ranges on demand instead.