#Performance#Rendering

Virtualized List

Ten thousand rows with only the visible window in the DOM, and a scrollbar that still behaves.

By Pratik RaiHard

Render a list of ten thousand rows while keeping only the ones on screen in the DOM — and keep the scrollbar behaving as though every row were present.

Virtualisation is two independent tricks, and describing them separately is most of the answer.

The first is lying to the scrollbar. A container as tall as every row combined gives the browser something to measure, so the scrollbar is the right length and scrollTop covers the right range even though only twenty elements exist. Without it the list scrolls one screen and stops.

The second is deriving the window from the scroll position. Fixed row heights turn "what is visible" into division, so nothing has to be measured and there is no layout read in the scroll path — which is exactly why the fixed-height version is what gets asked. Variable heights need measured offsets and a running total, and that is the follow-up rather than the starting point.

Offsetting the whole window with a single transform, rather than positioning each row absolutely, is worth choosing on purpose: it is one style property instead of one per row, and the rows stay in normal flow so borders and alternating backgrounds still compose. Absolute positioning is what forces most hand-rolled virtual lists to reimplement their own separators.

Note how this differs from infinite scrolling. There the data does not exist yet and the job is fetching more; here all the data is present and the DOM is the bottleneck. Real lists often need both.

Goal: Render only the rows in view while keeping scrolling and positioning correct.

Source

Frequently asked questions

What is list virtualization?
Rendering only the rows currently in view, while keeping the scroll container the size it would be if every row were present. The DOM stays small no matter how long the list is.
How does the scrollbar stay the right length?
An inner element is given the full height — row count times row height — so the browser measures that rather than the handful of rendered rows. Without it the list scrolls one screen and stops.
Why do fixed row heights make this easier?
Because the visible window becomes arithmetic: divide the scroll position by the row height. Nothing has to be measured, so there is no layout read in the scroll path. Variable heights need measured offsets and a running total.
How is this different from infinite scrolling?
Infinite scrolling fetches data that does not exist yet. Virtualization has all the data and is solving a DOM-size problem. Long real-world lists frequently need both at once.

Related Challenges

Continue learning with these related challenges

View All
React

Interdependent Inputs With Rollback

Four fields that constrain each other, where an invalid edit rolls back to its parent value instead of being clamped.

React · JavaScriptPratik Rai ·

React

Image Carousel

Create an interactive image carousel in React with smooth slide transitions, navigation arrows, dot indicators, autoplay, and touch/swipe support for mobile devices.

React · JavaScriptPratik Rai ·

React

Dynamic Tic Tac Toe

Build a dynamic Tic Tac Toe game in React with customizable grid sizes, win detection algorithms, player turn management, and game reset functionality. Great for interviews.

React · JavaScriptPratik Rai ·