Frontend Patterns

Pattern

Virtual Scrolling

Render only visible list items in the viewport to handle massive datasets efficiently.

Performance Advanced

Virtual Scrolling

Problem

Rendering thousands of list items creates massive DOM trees that freeze the browser. Scrolling becomes janky as the framework reconciles updates across hundreds of nodes. Memory usage spikes when displaying large datasets like transaction histories, chat logs, or product catalogs. The page becomes unresponsive with just a few thousand items.

Solution

Render only visible items in long lists by dynamically mounting and unmounting as users scroll. This keeps the DOM small and maintains smooth scrolling with thousands of items.

Example

This demonstrates rendering only visible list items in the viewport by dynamically mounting and unmounting as users scroll, enabling smooth performance with thousands of items.

import { FixedSizeList } from 'react-window';

function VirtualList({ items }) {
  return (
    <FixedSizeList
      height={600}              // Viewport height
      itemCount={items.length}  // Total number of items
      itemSize={50}             // Height of each item
      width="100%"
    >
      {({ index, style }) => (
        // Only renders items currently visible in viewport
        <div style={style}>{items[index].name}</div>
      )}
    </FixedSizeList>
  );
}

Benefits

  • Handles massive datasets without performance degradation.
  • Keeps DOM size constant regardless of list length.
  • Maintains smooth scrolling with thousands of items.
  • Dramatically reduces memory usage for large lists.

Tradeoffs

  • Adds complexity with virtualization libraries and configuration.
  • Can break features like browser search or screen reader navigation.
  • Requires fixed item heights or complex dynamic height calculations.
  • May have issues with nested scrolling or complex layouts.
Stay Updated

Get New Patterns
in Your Inbox

Join thousands of developers receiving weekly insights on frontend architecture patterns

No spam. Unsubscribe anytime.