Sikau

React patterns at scale · Day 8 · about 40 min

Memoization and virtualization

Skip renders and render only what's on screen.

Ten thousand orders

The kitchen's order history has ten thousand rows. Rendered naively, that's ten thousand components and ten thousand DOM nodes before the page can respond — and the field guide's performance chapter is blunt that main-thread JavaScript work is what makes pages feel slow, especially on mid-range phones. A person can see perhaps fifteen rows at a time. Why build the other 9,985?

Two techniques handle almost every slow list. Virtualization (also called windowing) renders only the rows in view. Memoization — memo, useMemo, useCallback — skips re-rendering rows whose inputs didn't change. Today you'll build both, the way react-window does underneath.

How windowing works

The Learning Patterns book describes the trick: a small scrolling container (the window), a big inner element with the full height so the scrollbar is right, and only the visible rows, absolutely positioned at top = index × rowHeight. As you scroll, the window moves and different rows are rendered.

const start = Math.max(0, Math.floor(scrollTop / itemHeight) - overscan);
const end = Math.min(items.length, Math.ceil((scrollTop + height) / itemHeight) + overscan);

<div className="viewport" style={{ height, overflowY: "auto" }} onScroll={(e) => setScrollTop(e.currentTarget.scrollTop)}>
  <div className="spacer" style={{ height: items.length * itemHeight, position: "relative" }}>
    {rows /* items start…end-1, each at top: i * itemHeight */}
  </div>
</div>
  • Overscan renders a few rows beyond each edge so fast scrolling doesn't flash blank space.
  • Rows of unknown height need measuring — that's what VariableSizeList and TanStack Virtual handle.
  • Ctrl+F can't find rows that aren't rendered, and screen readers only see the window: consider pagination for content people search.
  • Browsers also offer content-visibility: auto in CSS, which skips painting off-screen content while keeping it in the DOM.

The rest of this lesson

  • memo, useMemo and useCallbackexplain
  • How many rows?predict
  • Keep the handler stablefill
  • Pick the toolmatch
  • Window the order historywrite code
  • Badge quizquiz
  • What you learnedrecap

Continue this lesson free — run real code in your browser

Continue with Google

See all 10 lessons of React patterns at scale