List Virtualization (Windowing)
Rendering 10,000 rows creates 10,000+ DOM nodes. Layout, style recalculation, memory, and the initial render all scale with that number, so scrolling stutters. Virtualization (also called windowing) renders only the rows that are visible, plus a small buffer. List virtualization is what libraries such as react-window implement for you.
1. The Idea Behind List Virtualization
- A scroll container with a fixed height.
- An inner spacer element whose height equals the total height of all rows, so the scrollbar looks correct.
- Only the visible slice of rows is rendered, absolutely positioned (or translated) to where it would be in the full list.
2. The math (fixed row height)
const totalHeight = itemCount * rowHeight;
const startIndex = Math.max(0, Math.floor(scrollTop / rowHeight) - overscan);
const endIndex = Math.min(
itemCount - 1,
Math.ceil((scrollTop + viewportHeight) / rowHeight) + overscan,
);
// render items[startIndex..endIndex], each at top = index * rowHeight
Overscan renders a few extra rows above and below the viewport so fast scrolling does not reveal blank space.
3. A minimal implementation
function VirtualList({ items, rowHeight, height, overscan = 5, renderRow }) {
const [scrollTop, setScrollTop] = useState(0);
const start = Math.max(0, Math.floor(scrollTop / rowHeight) - overscan);
... premium content.