Performance & Virtualization
Performance & Virtualization
List virtualization (also called windowing) is a performance technique where only the list items currently visible in the viewport are rendered into the DOM. Items above and below the visible area are not rendered at all. As the user scrolls, items are dynamically rendered and destroyed. This allows lists of thousands of items to render as fast as lists of 20 items.
React.memo: Prevent Unnecessary Re-renders
JSX
import { memo, useCallback } from 'react'; // memo() wraps the component — only re-renders when props change const CourseItem = memo(function CourseItem({ course, onDelete }) { console.log('Rendered:', course.title); // only logs when this item's props change return ( <li> {course.title} <button onClick={() => onDelete(course.id)}>Delete</button> </li> ); }); function CourseList({ courses }) { const [other, setOther] = useState(0); // useCallback ensures onDelete has a stable reference across renders const handleDelete = useCallback((id) => { /* delete logic */ }, []); // stable — no dependencies return ( <div> <button onClick={() => setOther((n) => n + 1)}> Update other state ({other}) </button> {/* CourseItems do NOT re-render when 'other' changes */} <ul> {courses.map((c) => ( <CourseItem key={c.id} course={c} onDelete={handleDelete} /> ))} </ul> </div> ); }
Virtualization with react-window
JSX
// npm install react-window import { FixedSizeList } from 'react-window'; // Row renderer — receives index and style from react-window const Row = ({ index, style, data }) => ( <div style={style} className="list-row"> {data[index].title} </div> ); function HugeList({ items }) { return ( {/* Renders only the ~10 visible rows at a time, even if items has 50,000 entries */} <FixedSizeList height={600} // container height in px width={800} // container width in px itemCount={items.length} itemSize={56} // row height in px itemData={items} // passed to Row via data prop > {Row} </FixedSizeList> ); } /* Also available: VariableSizeList for rows of different heights For grids: FixedSizeGrid, VariableSizeGrid */
| List Size | Recommended Approach | Why |
|---|---|---|
| < 100 items | Standard .map() |
No optimization needed |
| 100 – 1,000 items | React.memo + useCallback |
Prevent unnecessary re-renders |
| > 1,000 items | react-window or react-virtual |
Virtualization — only render visible rows |
| Infinite scroll | react-infinite-scroll-component |
Load more items as user scrolls |
