react-window renders only visible items for large lists.
FixedSizeList (fixed height items):
1import { FixedSizeList } from "react-window";23const Row = ({ index, style }) => (4 <div style={style} className="row">5 Item {index}6 </div>7);89function App() {10 return (11 <FixedSizeList12 height={500}13 width="100%"14 itemCount={10000}15 itemSize={50}16 >17 {Row}18 </FixedSizeList>19 );20}
VariableSizeList (dynamic height items):
1import { VariableSizeList } from "react-window";23function App({ items }) {4 const getItemSize = (index) => {5 // Return different sizes based on content6 return items[index].long ? 100 : 50;7 };89 return (10 <VariableSizeList11 height={500}12 width="100%"13 itemCount={items.length}14 itemSize={getItemSize}15 >16 {({ index, style }) => (17 <div style={style}>18 {items[index].content}19 </div>20 )}21 </VariableSizeList>22 );23}
With dynamic data loading:
1import { FixedSizeList } from "react-window";2import useInfiniteScroll from "./useInfiniteScroll";34function VirtualList({ items, loadMore, hasMore }) {5 const observerRef = useInfiniteScroll(loadMore, hasMore);67 const Row = ({ index, style }) => (8 <div style={style}>9 {items[index]?.name}10 </div>11 );1213 return (14 <FixedSizeList15 height={500}16 width="100%"17 itemCount={items.length}18 itemSize={50}19 >20 {Row}21 </FixedSizeList>22 );23}
Benefits: