Mahamudul Hasan Rubel
HomeBlogCoursesAboutProjectsSkillsExperiencePhotosContact
Mahamudul Hasan Rubel

Senior Software Engineer crafting high-performance web applications and SaaS platforms.

Navigation

  • Home
  • Blog
  • Courses
  • About
  • Projects
  • Skills
  • Experience
  • Photos
  • Contact

Get in Touch

Available for senior/lead roles and consulting.

bd.mhrubel@gmail.comHire Me

Subscribe to the newsletter

Get new articles and course lessons delivered to your inbox. No spam, unsubscribe anytime.

© 2026 Mahamudul Hasan Rubel. All rights reserved.

Built with using Next.js 16 & Tailwind v4

Back to Blog
Lesson 39 of the Advanced React: Performance, Architecture & Patterns course
ReactJune 28, 20264 min read

Implementing Virtualized Lists: Performance at Scale

Learn how to implement virtualization in React to render massive datasets efficiently by mounting only visible components, ensuring smooth scroll performance.

reactjavascriptfrontend

Previously in this course, we explored The Key Prop Explained: Mastering React Lists and Performance to ensure correct reconciliation, and touched on the basics of Handling Large Datasets in UI: Performance, Tables, and UX. While pagination and infinite scrolling solve data fetching issues, they don't solve the "DOM bloat" problem. If your list contains 5,000 nodes, your browser's memory and layout engine will choke, regardless of how you fetch the data.

This lesson adds Virtualization (or "windowing") to your architecture. We will move beyond simple list rendering to a model where the DOM only contains the items currently visible in the viewport.

The First Principles of Virtualization

At its core, virtualization is the process of calculating the visible "window" of a scrollable area. If you have a list of 10,000 items, each 50px tall, but your container is only 500px high, you only ever need to render 10–12 items at once.

The browser doesn't care about the 9,990 items you aren't looking at. Virtualization replaces the list's actual height with a spacer element and absolutely positions the visible items within that space as the user scrolls.

The Virtualization Lifecycle

  1. Measurement: Calculate the height of the container and the estimated height of each item.
  2. Offset Calculation: Determine the current scroll position ($scrollTop$).
  3. Index Calculation: Determine the range of indices to render ($startIndex$ to $endIndex$).
  4. Rendering: Mount only the components within that range.
  5. Spacer Management: Adjust the top padding/transform of the container to keep the scrollbar accurate.

Implementing a Basic Virtualized List

While libraries like react-window are the industry standard for production, building a minimal version helps you understand the underlying mechanics.

JSX
import React, { useState, useRef, useMemo } from CE9178">'react';

const VirtualList = ({ items, itemHeight, containerHeight }) => {
  const [scrollTop, setScrollTop] = useState(0);
  const containerRef = useRef(null);

  const onScroll = (e) => setScrollTop(e.target.scrollTop);

  // Calculate visible range
  const startIndex = Math.floor(scrollTop / itemHeight);
  const endIndex = Math.min(
    items.length - 1,
    Math.floor((scrollTop + containerHeight) / itemHeight)
  );

  const visibleItems = useMemo(() => {
    const result = [];
    for (let i = startIndex; i <= endIndex; i++) {
      result.push(
        <div 
          key={i} 
          style={{ 
            position: CE9178">'absolute', 
            top: i * itemHeight, 
            height: itemHeight 
          }}
        >
          {items[i].content}
        </div>
      );
    }
    return result;
  }, [startIndex, endIndex, items, itemHeight]);

  return (
    <div 
      onScroll={onScroll} 
      style={{ height: containerHeight, overflow: CE9178">'auto', position: CE9178">'relative' }}
    >
      <div style={{ height: items.length * itemHeight, position: CE9178">'relative' }}>
        {visibleItems}
      </div>
    </div>
  );
};

Key Performance Considerations

  • Overscan: Always render a few extra items above and below the fold. This prevents "white flashes" if the user scrolls faster than the state can update.
  • Avoid Layout Thrashing: Notice we use position: absolute with top offsets. This allows us to update the list without triggering a full-page reflow.
  • Component Stability: Ensure the items rendered inside the list are memoized; otherwise, the parent list re-rendering will trigger unnecessary updates for every visible item.

Hands-on Exercise

  1. Create a VirtualizedList component using the logic provided above.
  2. Add an overscan prop that defaults to 5. Adjust the startIndex and endIndex calculations to include this buffer.
  3. Use the React DevTools Profiler to compare the re-render count of a standard map() list versus your new VirtualizedList when scrolling.

Common Pitfalls

  • Variable Row Heights: The example assumes fixed heights. If your items have dynamic heights (e.g., text content), you must implement a "measurement cache" or use a library like react-window with VariableSizeList.
  • Missing Keys: Even in virtualized lists, the key prop is non-negotiable. If you use the index as a key while items are being added/removed, your DOM reconciliation will break.
  • Ignoring Scroll Events: Binding to window.scroll is expensive. Always bind to a specific container's onScroll event and consider using a throttle if the list rendering logic is complex.

Recap

Virtualization is the most effective way to handle massive lists in React. By limiting the DOM nodes to only those visible in the viewport, you reduce memory footprint and keep the main thread free for user interactions. In our project, replace your long-running <List /> components with a virtualized implementation to ensure the dashboard remains responsive even as the data set grows to thousands of records.

Up next: We will begin Building Design System Primitives, focusing on how to create reusable, themed components that maintain performance while providing a consistent API for our application.

Previous lessonUsing Portals for UI OverlaysNext lesson Building Design System Primitives
Back to Blog

Similar Posts

ReactJune 28, 20263 min read

React custom hooks: How to fix stale closures for good

React custom hooks often suffer from stale closures. Learn how to track dependencies, use refs, and ensure your hooks always access the latest state.

Read more
ReactJune 28, 20264 min read

Handling Race Conditions in React: A Pro Guide

Learn to master race conditions in React by using cleanup functions, ignore flags, and AbortController to ensure your app state stays consistent.

Part of the course

Advanced React: Performance, Architecture & Patterns

advanced · Lesson 39 of 47

  1. 1

    Deep Dive into the Reconciliation Algorithm

    4 min
  2. 2

    Profiling with React DevTools

    3 min
  3. 3

    Establishing Performance Budgets

    3 min
Read more
ReactJune 26, 20263 min read

Testing Hooks and Components: Ensuring Quality in React

Master testing in React with React Testing Library. Learn to verify component state, mock API calls, and ensure high-quality code in your dashboard project.

Read more
  • 4

    Strategic use of React.memo

    3 min
  • 5

    Mastering useCallback and useMemo

    4 min
  • 6

    State Colocation Strategies

    4 min
  • 7

    Optimizing Context Providers

    4 min
  • 8

    Advanced Context Composition

    4 min
  • 9

    Eliminating Prop Drilling

    4 min
  • 10

    Introduction to Concurrent React

    4 min
  • 11

    Non-blocking UI with useTransition

    4 min
  • 12

    Handling Deferred Data with useDeferredValue

    3 min
  • 13

    Mastering Suspense for Data Fetching

    4 min
  • 14

    Streaming Server-Side Rendering

    3 min
  • 15

    Designing Compound Components

    3 min
  • 16

    The Render Props Pattern

    4 min
  • 17

    Implementing Control Props

    4 min
  • 18

    Headless UI Architectures

    3 min
  • 19

    Modular Directory Structures

    3 min
  • 20

    Refactoring Monolithic Components

    3 min
  • 21

    Optimistic UI Updates

    3 min
  • 22

    Advanced Cache Invalidation

    4 min
  • 23

    Handling Race Conditions

    4 min
  • 24

    Server-Client State Synchronization

    3 min
  • 25

    Route-level Code Splitting

    4 min
  • 26

    Offloading Tasks with Web Workers

    3 min
  • 27

    Advanced Error Boundaries

    3 min
  • 28

    Monitoring Production Performance

    4 min
  • 29

    Final Project Audit & Optimization

    4 min
  • 30

    Advanced Hook Patterns

    3 min
  • 31

    Managing Global State with Zustand/Redux

    4 min
  • 32

    Testing Performance-Critical Components

    4 min
  • 33

    Static Site Generation (SSG) Patterns

    4 min
  • 34

    Internationalization (i18n) Architecture

    3 min
  • 35

    Accessibility (a11y) in Advanced Components

    4 min
  • 36

    Managing Third-Party Integrations

    3 min
  • 37

    Advanced Form Handling

    4 min
  • 38

    Using Portals for UI Overlays

    4 min
  • 39

    Implementing Virtualized Lists

    4 min
  • 40

    Building Design System Primitives

    3 min
  • 41

    Managing Large-Scale Data Fetching

    4 min
  • 42

    Micro-Frontends with React

    4 min
  • 43

    Security Best Practices in React

    3 min
  • 44

    Advanced Ref Usage

    Coming soon
  • 45

    Memoization Pitfalls

    Coming soon
  • 46

    Mastering React Patterns for Scalability

    Coming soon
  • 47

    Advanced TypeScript with React

    Coming soon
  • View full course