Virtual scrolling for lists over 100 items
Why it matters
Rendering 500 list items in the DOM simultaneously creates 500 DOM nodes with layout, paint, and event handling overhead — even for items the user cannot see. Scroll performance on a fully-rendered 10,000-row table degrades to 10–20fps on mid-range devices because every scroll event triggers layout recalculation for all 10,000 nodes. ISO 25010:2011 resource-utilisation captures the memory cost; the user-visible failure is a janky, unresponsive list that makes the application feel broken for users browsing large datasets.
Severity rationale
Info because virtual scrolling is an optimization for large lists — its absence only matters when the list exceeds 100 items, and many applications avoid this scenario through pagination or search.
Remediation
Replace full-render lists with a windowing library. react-window (lightweight) and @tanstack/react-virtual (flexible) both render only visible rows.
// components/product-list.tsx — virtual scrolling for 100+ items
import { FixedSizeList, ListChildComponentProps } from 'react-window'
function Row({ index, style }: ListChildComponentProps) {
return <div style={style}>{products[index].name}</div>
}
export function ProductList({ products }: { products: Product[] }) {
return (
<FixedSizeList
height={600}
itemCount={products.length}
itemSize={48}
width="100%"
>
{Row}
</FixedSizeList>
)
}
Detection
-
ID:
virtual-scrolling-lists -
Severity:
info -
What to look for: Count all list components rendering arrays. Enumerate which render over 100 items and whether they use virtual scrolling. Find list components or data tables that render many items (100+). Check whether they use virtual scrolling or windowing libraries (react-window, react-virtual, Recharts virtualization). Measure DOM node count for large lists.
-
Pass criteria: Lists with 100+ items use virtual scrolling. Only visible items are rendered in DOM. Scroll performance stays at 60fps.
-
Fail criteria: Large lists render all items in DOM, causing excessive DOM nodes and scroll jank.
-
Skip (N/A) when: The application has no lists with 100+ items, or all lists are paginated.
-
Cross-reference: For DOM node count limits, see
dom-node-count-limit. -
Detail on fail:
"Data table with 10,000 rows renders all rows in DOM — causes 30fps scroll performance"or"No virtual scrolling detected on 500-item select dropdown" -
Remediation: Implement virtual scrolling using react-window or react-virtual for large lists.
// components/data-list.tsx — virtual scrolling for 100+ items import { FixedSizeList } from 'react-window' <FixedSizeList height={400} itemCount={items.length} itemSize={35}>{({ index, style }) => <div style={style}>{items[index]}</div>}</FixedSizeList>
External references
- iso-25010:2011 · performance-efficiency.resource-utilization — Resource Utilisation (performance efficiency)
Taxons
History
- 2026-04-18·v1.0.0·Initial import from performance-deep-dive·automated