react-virtualized and react-window are virtualization libraries that recycle DOM nodes to render large lists efficiently without slowing down the browser. rc-virtual-list is a virtual list component often used within the Ant Design ecosystem, supporting variable heights and smooth scrolling. react-infinite-scroll-component focuses on the interaction pattern of loading more data as the user scrolls, appending new items to the DOM rather than recycling existing nodes. Choosing the right tool depends on whether you need to render thousands of items at once (virtualization) or load data in chunks as the user navigates (infinite loading).
When building data-heavy React applications, rendering performance becomes a critical concern. react-virtualized, react-window, and rc-virtual-list solve this by virtualization ā rendering only the visible items. react-infinite-scroll-component takes a different approach by loading more data as the user scrolls. Let's compare how they handle common engineering challenges.
react-window recycles DOM nodes.
// react-window: FixedSizeList
import { FixedSizeList } from 'react-window';
<List height={500} itemCount={1000} itemSize={35} width={300}>
{({ index, style }) => (
<div style={style}>Row {index}</div>
)}
</List>
react-virtualized also recycles DOM nodes.
rowRenderer functions.// react-virtualized: List
import { List } from 'react-virtualized';
<List
height={500}
rowCount={1000}
rowHeight={35}
rowRenderer={({ index, style }) => (
<div key={index} style={style}>Row {index}</div>
)}
width={300}
/>
rc-virtual-list recycles DOM nodes.
data array directly and maps over it internally.// rc-virtual-list: List
import List from 'rc-virtual-list';
<List data={items} height={500} itemHeight={35}>
{item => (
<div key={item.id}>{item.name}</div>
)}
</List>
react-infinite-scroll-component appends DOM nodes.
// react-infinite-scroll-component: InfiniteScroll
import InfiniteScroll from 'react-infinite-scroll-component';
<InfiniteScroll
dataLength={items.length}
next={fetchMore}
hasMore={true}
height={500}
>
{items.map(item => <div key={item.id}>{item.name}</div>)}
</InfiniteScroll>
react-window uses a function child for rendering.
index and style.// react-window: Function child
<FixedSizeList itemCount={100} itemSize={20}>
{({ index, style }) => <div style={style}>{index}</div>}
</FixedSizeList>
react-virtualized uses a dedicated rowRenderer prop.
key and style explicitly.// react-virtualized: rowRenderer prop
<List
rowCount={100}
rowHeight={20}
rowRenderer={({ index, style }) => <div style={style}>{index}</div>}
/>
rc-virtual-list uses a function child like React maps.
item data directly.// rc-virtual-list: Function child with data
<List data={items} itemHeight={20}>
{item => <div key={item.id}>{item.name}</div>}
</List>
react-infinite-scroll-component renders standard children.
// react-infinite-scroll-component: Standard children
<InfiniteScroll dataLength={items.length} next={fetchMore} hasMore={true}>
{items.map(item => <div key={item.id}>{item.name}</div>)}
</InfiniteScroll>
react-window supports variable heights via VariableSizeList.
itemSize function.resetAfterIndex when data changes.// react-window: VariableSizeList
import { VariableSizeList } from 'react-window';
<VariableSizeList
itemCount={items.length}
itemSize={index => getHeight(items[index])}
>
{({ index, style }) => <div style={style}>{items[index].name}</div>}
</VariableSizeList>
react-virtualized supports variable heights via rowHeight function.
recomputeRowHeights to update.// react-virtualized: Variable rowHeight
<List
rowCount={items.length}
rowHeight={({ index }) => getHeight(items[index])}
rowRenderer={({ index, style }) => <div style={style}>{items[index].name}</div>}
/>
rc-virtual-list supports variable heights via itemHeight function.
// rc-virtual-list: Variable itemHeight
<List
data={items}
itemHeight={item => getHeight(item)}
>
{item => <div key={item.id}>{item.name}</div>}
</List>
react-infinite-scroll-component supports variable heights naturally.
// react-infinite-scroll-component: Natural CSS height
<InfiniteScroll dataLength={items.length} next={fetchMore} hasMore={true}>
{items.map(item => (
<div key={item.id} style={{ height: getHeight(item) }}>
{item.name}
</div>
))}
</InfiniteScroll>
react-window is actively maintained.
react-virtualized.// react-window: Current standard
import { FixedSizeList } from 'react-window';
// Actively updated and supported
react-virtualized is in maintenance mode.
react-window.// react-virtualized: Legacy
import { List } from 'react-virtualized';
// Superseded by react-window; use only for legacy support
rc-virtual-list is actively maintained.
// rc-virtual-list: Active
import List from 'rc-virtual-list';
// Maintained alongside Ant Design ecosystem
react-infinite-scroll-component is actively maintained.
// react-infinite-scroll-component: Active
import InfiniteScroll from 'react-infinite-scroll-component';
// Maintained for infinite loading use cases
| Feature | react-window | react-virtualized | rc-virtual-list | react-infinite-scroll-component |
|---|---|---|---|---|
| Mechanism | š Virtualization | š Virtualization | š Virtualization | š„ Appending |
| API Style | š§© Render Prop | š§© Row Renderer | š¦ Data Prop | š¦ Children |
| Variable Height | ā Manual Reset | ā Manual Reset | ā Auto Handle | ā Natural CSS |
| Status | š¢ Active | š” Maintenance | š¢ Active | š¢ Active |
| Best For | ā” Performance | š°ļø Legacy Support | š¢ AntD Integration | š Feed Loading |
react-window is the modern standard for virtualization ā choose it for high-performance lists in new projects. It balances speed with a clean API.
react-virtualized is a legacy tool ā keep it only if you are maintaining older code. Migrating to react-window is recommended for long-term health.
rc-virtual-list is the enterprise choice ā ideal if you use Ant Design or need robust variable height support without extra boilerplate.
react-infinite-scroll-component is the interaction specialist ā use it when you need to load data in chunks rather than render a massive static list.
Final Thought: Virtualization libraries recycle DOM nodes to save memory, while infinite scroll components load more data over time. Pick based on whether your bottleneck is rendering speed or data volume.
Choose rc-virtual-list if you are already using Ant Design or need a virtual list that handles variable row heights with minimal setup. It is well-suited for tables and lists within enterprise dashboards where integration with AntD components is a priority. This package manages scrolling and rendering efficiently while keeping the API simple for data-driven lists.
Choose react-infinite-scroll-component if your primary goal is to load more data from a server as the user reaches the bottom of the page. It is ideal for social feeds or search results where the total dataset is unknown or too large to virtualize effectively. Note that it does not recycle DOM nodes by default, so performance may degrade if too many items are loaded without additional optimization.
Choose react-virtualized only if you are maintaining a legacy codebase that already depends on it, as it is now in maintenance mode. It offers a wide range of complex grid and list features but has a heavier bundle size and steeper learning curve than newer alternatives. For new projects, consider react-window instead, as it is the recommended successor by the original author.
Choose react-window for new projects requiring high-performance virtualization of large lists or grids. It is lighter and simpler than react-virtualized, with a modern API that focuses on fixed or variable-sized items. This package is the standard choice for rendering thousands of rows without impacting scroll performance or memory usage.
React Virtual List Component which worked with animation.
https://virtual-list-react-component.vercel.app/
npm install
npm start
open http://localhost:8000/
import List from 'rc-virtual-list';
<List data={[0, 1, 2]} height={200} itemHeight={30} itemKey="id">
{index => <div>{index}</div>}
</List>;
| Prop | Description | Type | Default |
|---|---|---|---|
| children | Render props of item | (item, index, props) => ReactElement | - |
| component | Customize List dom element | string | Component | div |
| data | Data list | Array | - |
| disabled | Disable scroll check. Usually used on animation control | boolean | false |
| height | List height | number | - |
| itemHeight | Item minimum height | number | - |
| itemKey | Match key with item | string | - |
| styles | style | { horizontalScrollBar?: React.CSSProperties; horizontalScrollBarThumb?: React.CSSProperties; verticalScrollBar?: React.CSSProperties; verticalScrollBarThumb?: React.CSSProperties; } | - |
children provides additional props argument to support IE 11 scroll shaking.
It will set style to visibility: hidden when measuring. You can ignore this if no requirement on IE.