how-to
How to virtual-scroll a million rows without pagination
Last updated 22 September 2026
Generate a million rows in a loop, hand the array to createGrid with a
rowKey and nothing else, and it stays responsive. There is no paging control,
no "load more" button and no separate large-data mode to switch on: the grid mounts only the
rows currently in view as DOM elements and swaps them as the viewport moves, so scroll and
paint cost track the screen, not the array.
Below is a live grid holding a million rows. Scroll it, click a column header to sort, or type into the quick filter, all at the speed you would expect from a dozen rows.
The code
A loop builds the array and one call to createGrid is the entire configuration.
Sorting, filtering, resizing and reordering all work without being asked for.
const rows = [];
for (let i = 0; i < 1_000_000; i++) {
rows.push({ id: i + 1, name: `Record ${i + 1}`, region, value, date });
}
const grid = LatticeGrid.createGrid(document.getElementById('grid'), {
rowKey: 'id',
columns: [/* id, name, region, value, date */],
rows,
});
Try the standalone page or read the full source on GitHub, loaded by script tag with no build step.
Two things to know
- The million rows live in memory as a plain array. That is the memory source, the grid's default, and it is the design target: it fits comfortably up to roughly a million rows across dozens of columns before a paged or remote source is worth reaching for.
- Only the visible band of rows, plus a small overscan either side, is ever mounted in the DOM. A sort or a filter re-ranks the underlying array; it does not change how many DOM rows exist.
See the full million-row demo for the row count and generation time, or the memory source guide for how the pipeline behind it works.