Challenges📊 Data-IntensiveBuild a Virtualized Data Table
ðŸĶ–DinosaurPerformanceReactUI Components

Build a Virtualized Data Table

Design a high-performance data table that handles 100K rows with sorting, filtering, and column resizing.

Build a Virtualized Data Table

Requirements

  • Handle 100K+ rows smoothly
  • Column sorting (client-side for small sets, server-side for large)
  • Text filtering and search
  • Column resizing and reordering
  • Row selection
  • Keyboard navigation

Core Concept: Virtualization

Only render rows visible in the viewport + a small overscan buffer:

Total rows: 100,000
Viewport height: 600px
Row height: 40px
Visible rows: 15
Overscan: 5 above + 5 below
Actually rendered: ~25 DOM nodes (not 100,000)

Architecture

DataSource → Transform Pipeline → Virtual Window → Rendered Rows
              (sort, filter,       (visible range    (actual DOM)
               group)               calculation)

The Virtual Scroller

function VirtualTable({ data, rowHeight, containerHeight }) {
  const [scrollTop, setScrollTop] = useState(0);
  const overscan = 5;
 
  const startIndex = Math.max(0, Math.floor(scrollTop / rowHeight) - overscan);
  const endIndex = Math.min(
    data.length,
    Math.ceil((scrollTop + containerHeight) / rowHeight) + overscan
  );
 
  const visibleRows = data.slice(startIndex, endIndex);
  const totalHeight = data.length * rowHeight;
  const offsetY = startIndex * rowHeight;
 
  return (
    <div
      style={{ height: containerHeight, overflow: 'auto' }}
      onScroll={(e) => setScrollTop(e.currentTarget.scrollTop)}
    >
      <div style={{ height: totalHeight, position: 'relative' }}>
        <div style={{ transform: `translateY(${offsetY}px)` }}>
          {visibleRows.map((row, i) => (
            <Row key={startIndex + i} data={row} height={rowHeight} />
          ))}
        </div>
      </div>
    </div>
  );
}

Variable Row Heights

When rows have dynamic content, pre-measure or estimate heights. Use a position cache and binary search for scroll-to-index.

Performance Considerations

  1. Avoid layout thrashing — batch reads and writes
  2. Use CSS contain — contain: strict on the scroll container
  3. Debounce scroll events — or use requestAnimationFrame
  4. Memoize row components — React.memo with stable keys

The key insight: virtualization trades DOM node count for scroll calculation complexity. The math is cheap; DOM operations are expensive.