Skip to the solution
HardFrontend6 min read

Implement a Virtualized List That Renders Only Visible Rows

764 views

The problem

Problem, as an interviewer would state it: "Given a scroll position and a list of 10,000+ items, compute which small RANGE of item indices actually needs to be rendered — the entire real point being that a real browser genuinely cannot render 10,000 real DOM nodes efficiently."

Examples:

Code
getVisibleRange({ scrollTop: 4000, viewportHeight: 400, itemHeight: 40, totalItems: 10000 });
// { start: 98, end: 112, count: 15 } -- NOT all 10000

Clarifying questions expected:

  • Should the range include extra "overscan" items just outside the visible viewport, to reduce flicker during fast scrolling?
  • Are all items a fixed, uniform height, or could they genuinely vary?
  • Does the container need a real spacer element to maintain correct scrollbar proportions, given only a handful of real DOM nodes actually exist?

Code / implementation expected: Yes — real, direct proof across multiple real scroll positions confirming only a small, bounded window is ever computed as needing to render, never anywhere close to the full item count.

  • performance
  • dom
  • virtualization

Try it yourself

Sketch your approach before you read the solution. That is what the interview tests.

Stuck? Get a hint.

A short nudge toward the approach. It will not give the answer away.

Solution

The solution is hidden so you can try first

6 min read · 9 sections

Run the code

Edit the code and run it here. Each console line with an expected value becomes a test.

JavaScriptReal, direct proof: the visible-range calculation stays small (never more than ~15 items) across multiple real scroll positions in a 10,000-item list

Discussion

Other approaches, follow-ups and how it went in real interviews.

Sign in to join the discussion.

No comments yet. Share how you would answer it.

Question 145 of 154 in JavaScript coding

Keep your momentum going.

Mark this question solved to track your progress, then take the next one while it is fresh.

Up nextHard

Implement a minimal Promise/A+ (MyPromise) with then/catch

Continue