Virtualizing Variable-Height Lists
Fixed-height virtualization is simple arithmetic. Real feeds (chat messages, social posts, comments) have rows whose heights depend on content, so you cannot compute positions with index * rowHeight. Here is how production virtualizers handle it. Virtualizing variable-height lists is exactly what libraries like TanStack Virtual do under the hood.
1. Estimate, then measure
- Start with an estimated height for every row (for example, 80px) so the total height and scrollbar are roughly right.
- When a row renders, measure its real height (via a ref and
getBoundingClientRect, or aResizeObserverto catch later changes such as images loading). - Store measured heights in a cache keyed by item id.
2. Offsets via prefix sums
Each row’s top position is the sum of heights of all rows before it.
offset[0] = 0
offset[i] = offset[i - 1] + height(i - 1) // measured or estimated
To find the first visible row for a given scrollTop, binary search the offsets array, which takes O(log n) instead of scanning every row.
3. Scroll anchoring
When a row above the viewport gets measured and turns out taller than estimated, every row below shifts down and the content the user is reading jumps. Fixes:
- Adjust
scrollTopby the... premium content.
