DEV Community

Cover image for Virtualization โ€” Architecture Series: Part 3
MUHAMMAD USMAN AWAN
MUHAMMAD USMAN AWAN

Posted on

Virtualization โ€” Architecture Series: Part 3

๐Ÿš€ Virtualization in Frontend (React)

โœ… What is Virtualization?

Virtualization (sometimes called windowing) is a rendering optimization technique where the UI renders only the elements visible inside the viewport, instead of rendering all items at once.

๐Ÿ”ฅ Instead of creating 10,000 DOM nodes, you render maybe ~20.
The rest exist โ€œvirtuallyโ€ in memory.

Scenario DOM Nodes Rendered Memory FPS Time to Interactive
โŒ Without Virtualization 10,000 ~500MB ~5 FPS ~30 seconds
โœ… With Virtualization ~20 ~50MB 60 FPS <1 second

๐Ÿ“Œ Core idea:
Maintain the entire dataset in memory โ†’ render only the subset currently visible in the scroll area.


๐Ÿšง Why do we need virtualization?

Bad approach (renders every item):

function ChatMessages({ messages }) {
  return (
    <div className="messages">
      {messages.map(msg => (
        <MessageCard key={msg.id} message={msg} />
      ))}
    </div>
  );
}
Enter fullscreen mode Exit fullscreen mode

โ— Problems:

  • DOM explosion (10,000 nodes)
  • Massive memory use
  • Lags, FPS drops
  • Browser crashes on mobile

โœ… Benefits of Virtualization

  1. Performance stays constant regardless of data size
  2. Low memory usage โ€” only visible items exist in DOM
  3. Smooth scrolling (60 FPS) even with millions of rows
  4. Fast initial load โ€” only a few elements render
  5. Mobile friendly โ€” avoids browser memory crash


๐Ÿง  How Virtualization Works (Visually)

Viewport (visible area):
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚ Item 48             โ”‚  <- Rendered
โ”‚ Item 49             โ”‚  <- Rendered
โ”‚ Item 50             โ”‚  <- Rendered
โ”‚ Item 51             โ”‚  <- Rendered
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
โ†‘ User is seeing these 4 items now

Items 1โ€“47: not rendered
Items 52โ€“10000: not rendered
Enter fullscreen mode Exit fullscreen mode

โžก๏ธ Scroll โ†’ remove old items โ†’ render new ones.


๐Ÿงฎ Key Calculations (how react-window / react-virtuoso work internally)

const itemHeight = 80;      // px
const containerHeight = 600; // px
const scrollTop = 3840;      // user scroll position

const visibleCount = Math.ceil(containerHeight / itemHeight); // ~8 items
const startIndex = Math.floor(scrollTop / itemHeight);        // start at item 48
const endIndex = startIndex + visibleCount + 1;               // overscan
Enter fullscreen mode Exit fullscreen mode

Only items 48โ€“57 are rendered, not all 10,000.


โœ… Implementation Levels

1๏ธโƒฃ Build Virtualization from Scratch (fixed height)

Use for chat, lists, tables, logs where every item height is known.

โœ… Only renders visible items
โœ… Simple math

function VirtualList({ items, itemHeight, containerHeight }) {
  const [scrollTop, setScrollTop] = useState(0);
  const visibleCount = Math.ceil(containerHeight / itemHeight);

  const startIndex = Math.floor(scrollTop / itemHeight);
  const endIndex = startIndex + visibleCount + 1;

  const visibleItems = items.slice(startIndex, endIndex);
  const offsetY = startIndex * itemHeight;

  return (
    <div
      onScroll={(e) => setScrollTop(e.target.scrollTop)}
      style={{ height: containerHeight, overflow: "auto" }}
    >
      <div style={{ height: items.length * itemHeight, position: "relative" }}>
        <div style={{ transform: `translateY(${offsetY}px)` }}>
          {visibleItems.map((item, i) => (
            <div key={startIndex + i} style={{ height: itemHeight }}>
              {item.text}
            </div>
          ))}
        </div>
      </div>
    </div>
  );
}
Enter fullscreen mode Exit fullscreen mode

2๏ธโƒฃ Virtualization with Variable Height Items

Use when item height is unknown (tweets, chat messages with images, markdown).

โœจ After rendering, measure the height and update.

(Your code above is already perfect; leaving as-is.)

3๏ธโƒฃ Production Ready: react-window

Lightweight, battle-tested, perfect for fixed height rows.

import { FixedSizeList } from "react-window";

function MessageList({ messages }) {
  return (
    <FixedSizeList
      height={600}
      itemCount={messages.length}
      itemSize={80}
      width="100%"
    >
      {({ index, style }) => (
        <div style={style}>
          <MessageCard message={messages[index]} />
        </div>
      )}
    </FixedSizeList>
  );
}
Enter fullscreen mode Exit fullscreen mode

4๏ธโƒฃ Best option today: react-virtuoso

Handles everything automatically โ€” dynamic height, infinite scroll, sticky headers.

import { Virtuoso } from "react-virtuoso";

function ChatMessages({ messages }) {
  return (
    <Virtuoso
      data={messages}
      style={{ height: "600px" }}
      itemContent={(index, message) => (
        <MessageCard message={message} />
      )}
    />
  );
}
Enter fullscreen mode Exit fullscreen mode

๐ŸŒ Real-World Examples

โœ… WhatsApp style chat (scroll to load older messages)
โœ… Twitter feed (infinite scroll + pull to refresh)
โœ… Gmail inbox (checkboxes + selection + virtualization)

(Your examples above remain unchanged โ€” they are production ready.)


๐Ÿ”ฅ Best Practices / Gotchas

Problem Solution
Scroll jumps when loading older messages Maintain firstItemIndex (Virtuoso handles this)
Images inside list change row height Use resetAfterIndex or Virtuoso auto measuring
Items re-render unnecessarily memo() your row component
Searching / filtering Debounce search to avoid re-rendering

TL;DR

Virtualization = render fewer DOM nodes โ†’ better performance.

  • Instead of rendering 10,000 DOM nodes
  • You render ~20 and recycle them as user scrolls
  • Result: smooth 60 FPS scrolling even with huge datasets

And thatโ€™s it โ€” you now understand virtualization: what it is, why it matters, and how to implement it efficiently in UI. From optimizing DOM nodes to ensuring smooth scrolling, virtualization keeps your UI fast even with thousands of items.

If you havenโ€™t seen the previous parts yet, give them a look. Each part builds on the last, and together theyโ€™ll level up your performance game.

Top comments (0)