CONCEPT Cited by 2 sources
List virtualization¶
Definition¶
List virtualization (a.k.a. windowing) is a front-end rendering technique for long scrollable lists: mount only the rows currently on screen (plus a small over-scan margin), and recycle those same DOM elements as the user scrolls, so the mounted DOM stays roughly constant no matter how many logical rows exist. The list behaves as if all N rows are present — the scrollbar is the right size, scroll-to-row works — but only ~100 rows are ever real in the DOM at once. You cannot put a million DOM nodes on a page; virtualization is the standard answer (Source: sources/2026-09-23-github-rendering-huge-pull-requests-in-the-github-copilot-app).
The geometry that makes it work¶
The illusion requires something to supply the geometry:
- Scrollbar height = the sum of all row heights.
- Position of row N = the sum of the heights of the rows above it.
- Jumping to a row, drawing the scrollbar, deciding what's on screen — all arithmetic over a table of heights.
Two regimes for that table:
- Known heights up front ("all heights known before paint"). If every row is a fixed, predictable height — e.g. a line of code at a known font size — the whole height table is computed once and never corrected. Offset math is a prefix sum; a typed array is enough. No per-frame work grows with total row count. This is the ideal case.
- Variable heights (estimate → measure → correct). General-purpose variable-height virtualizers build the table from estimates and correct entries as rows are measured after paint. The hazard: writing a corrected height back into a shared offset table shifts everything below it while the user is scrolling — a scroll jump. Mitigations: measure lazily, scope measurement to the viewport, and apply corrections anchored to what the user is looking at rather than to a pixel coordinate (Source: sources/2026-09-23-github-rendering-huge-pull-requests-in-the-github-copilot-app).
When one geometry isn't enough: split the domains¶
The hard case is a list with both fixed-height rows and unpredictable-height items (e.g. a code diff interleaved with review comments whose height depends on markdown wrapping, expandable sections, an inline composer, and images that load after paint). GitHub's Copilot-app PR view splits the document into two independent height domains:
total height = deterministic code height (exact, prefix-summed, never rebuilt)
+ Σ dynamic-block effective height (estimated, then measured lazily)
+ scroll padding
so a resizing comment never forces the deterministic code geometry to be rebuilt, and the number of unpredictable blocks is bounded by comments (a few thousand) rather than by rows (a million). Dynamic blocks are keyed by identity (stable key + file/line/side anchor + content fingerprint + width bucket), so a reflow can't lose track of one and an ordinary window resize doesn't invalidate every measurement (Source: sources/2026-09-23-github-rendering-huge-pull-requests-in-the-github-copilot-app).
Trade-offs¶
- Wins: bounded DOM node count and bounded per-frame work regardless of list length — a million-row list scrolls like a small one. GitHub reports ~100 real rows mounted at once and a 10× reduction in JS heap + DOM nodes at the p95 diff tail (Source: sources/2026-04-03-github-the-uphill-climb-of-making-diff-lines-performant).
- Cost: native browser find-in-page breaks on virtualized content (rows not in the DOM can't be found by the browser) — GitHub calls this out as an explicit trade. Variable-height virtualization adds the scroll-jump hazard above and requires an off-the-hot-path measurement scheduler to keep corrections from causing jank.
Seen in¶
- sources/2026-09-23-github-rendering-huge-pull-requests-in-the-github-copilot-app — canonical wiki instance of mixed-height virtualization: the two-geometry split (deterministic code rows + estimate-then-measure comment blocks), keying dynamic blocks by identity, and anchor-preserving scroll correction on a 2,200-file / >1M-line / >400-comment PR.
- sources/2026-04-03-github-the-uphill-climb-of-making-diff-lines-performant
— the sibling web Files-changed tab rewrite uses
TanStack Virtual window virtualization for
10,000-line PRs: only the visible window is in the DOM, 10× heap/DOM reduction, INP 275-700+ ms → 40-80 ms, at the cost of native find-in-page.
Related¶
- systems/github-copilot-pr-view — mixed-height (code + comments) virtualization.
- systems/github-pull-requests — web diff surface, TanStack-Virtual windowing.
- systems/tanstack-virtual — a general-purpose variable-height virtualizer.
- concepts/hot-path — measurement/correction is kept off the per-frame hot path.
- concepts/streaming-ssr — server-side sibling: hydrate/stream visible content first.
- window-virtualization, windowing, dom-node-count — synonyms / adjacent vocabulary.