DEV Community

Cover image for ๐Ÿš€ ๐—ก๐—ฒ๐˜„ ๐—ฅ๐—ฒ๐—ฎ๐—ฐ๐˜ ๐—–๐—ต๐—ฎ๐—น๐—น๐—ฒ๐—ป๐—ด๐—ฒ: Virtualized List
ReactChallenges
ReactChallenges

Posted on Originally published at reactchallenges.com

๐Ÿš€ ๐—ก๐—ฒ๐˜„ ๐—ฅ๐—ฒ๐—ฎ๐—ฐ๐˜ ๐—–๐—ต๐—ฎ๐—น๐—น๐—ฒ๐—ป๐—ด๐—ฒ: Virtualized List

Ever hit a wall when a list grows to thousands of rows and React starts to choke? Mounting 10,000 DOM nodes at once is the problem โ€” rendering only what fits on screen is the fix.


๐Ÿงฉ Overview

Build a virtualized list of 10,000 contacts that mounts only the rows visible in the scroll viewport (plus a small overscan), using fixed row heights and windowing math.

๐Ÿ‘‰ https://www.reactchallenges.com/challenges/virtualized-list


โœ… Requirements

  • Render a virtualized directory of 10,000 contacts.
  • Mount only a small window of rows โ€” far fewer than the 10,000 in the dataset.
  • Scroll through the entire dataset, not just the mounted rows.
  • Size the scrollable area to the full dataset so the scrollbar spans the whole list.
  • Unmount rows that leave the viewport and mount the ones that enter it.
  • Keep a few overscan rows above and below the visible window.
  • Show the first and last mounted rows in a stats line: Showing Xโ€“Y of 10000.
  • Display each contact's name and email in its row.

๐Ÿ’ก Notes

  • Put all the windowing logic in App.tsx: track scrollTop, measure the viewport's clientHeight, and compute the range of rows to mount.
  • Measure the viewport height in a layout effect โ€” it's the moment the layout is ready.
  • Clamp the range so overscan never renders rows before the first or after the last contact.

๐Ÿงช Tests

  1. Renders the app title
  2. Only mounts a small window of rows, not the whole dataset
  3. Renders the first contacts on load
  4. Sizes the scrollable area to the full dataset
  5. Shows the first and last rendered rows in the stats
  6. Renders more rows than fit on screen (overscan)
  7. Shows the name and email for each mounted row
  8. Moves the window down when scrolling
  9. Restores the first rows when scrolling back to the top
  10. Renders the last contact when scrolled to the bottom
  11. Mounts overscan rows above the visible window when scrolled
  12. Never renders rows above the first one

This challenge is a hands-on way to understand virtualization from scratch โ€” the exact pattern behind every serious long-list library. Practice windowing math, useLayoutEffect, and derived rendering, and your lists will stop freezing for good.

๐Ÿ”ฅ Start the Challenge Now

Top comments (0)