Skip to content

Virtualization

Virtualization renders only visible list items in the DOM — not all 10,000 rows. Scroll position maps to which slice of data renders, keeping memory and paint cost low.

Windowing Large Lists

Without virtualization, 10k DOM nodes slow scrolling and increase memory. Virtualizers compute visible range from scroll offset and item height, rendering ~20 rows regardless of total count.

TanStack Virtual (@tanstack/react-virtual) and react-window are popular React virtualizers.

import { useVirtualizer } from '@tanstack/react-virtual';

function VirtualList({ items }) {
  const parentRef = useRef(null);
  const virtualizer = useVirtualizer({
    count: items.length,
    getScrollElement: () => parentRef.current,
    estimateSize: () => 48,
  });

  return (
    <div ref={parentRef} style={{ height: 400, overflow: 'auto' }}>
      <div style={{ height: virtualizer.getTotalSize() }}>
        {virtualizer.getVirtualItems().map(vRow => (
          <div key={vRow.key} style={{ transform: `translateY(${vRow.start}px)` }}>
            {items[vRow.index].name}
          </div>
        ))}
      </div>
    </div>
  );
}

Only visible virtual items mount — scroll updates which indices render.

When to Virtualize

> 100-500 rows with complex cells → consider
> 1000+ simple rows → strongly recommend
< 50 rows → usually unnecessary
  • Fixed row height simplifies calculations; variable height needs measurement.
  • Virtualize tables, feeds, logs, and autocomplete dropdowns.
  • Combine with infinite scroll / paginated fetch for server data.
  • Test scroll performance on low-end devices.

Virtualization Libraries

Popular React virtualization options.

Library Notes
TanStack Virtual Headless, flexible, modern
react-window Lightweight, fixed/variable size
react-virtuoso Batteries included, auto height
AG Grid Full data grid with built-in virtualization
CSS contain Complementary perf hint

Variable Row Heights

Dynamic content heights require measuring rows or estimating with correction. TanStack Virtual supports dynamic measurement via measureElement.

Virtualize vs Paginate

Pagination reduces data fetched and rendered. Virtualization renders large client-side datasets smoothly. Often combine: fetch pages, virtualize current page.

Common Mistakes

  • Virtualizing tiny lists — unnecessary complexity.
  • Wrong total height container breaking scroll.
  • Missing keys on virtual rows.
  • Not accounting for variable row heights.

Key Takeaways

  • Virtualization renders visible items only.
  • Essential for thousands of rows in the DOM.
  • TanStack Virtual and react-window are common choices.
  • Combine with pagination for server-backed data.

Pro Tip

Before virtualizing, confirm slowness is DOM count — not slow render per row. Fix row component first if each row is expensive.