react-virtualized、react-window、react-virtual は、React アプリケーションで数千行を超えるリストやテーブルをパフォーマンス低下なく表示するためのライブラリです。これらは「ウィンドウ化」(仮想化)技術を用いて、現在画面に見えているアイテムだけをレンダリングし、スクロールに応じて内容を入れ替える仕組みを持っています。react-virtualized はかつての標準でしたが、現在は react-window への移行が推奨されています。react-virtual はフックベースのヘッドレスアプローチを提供しますが、現在は @tanstack/react-virtual へ統合されています。
React で数千件以上のデータを表示する際、すべてを一度に描画するとブラウザが重くなり操作不能になります。これを防ぐため、見える部分だけを描画する「仮想化」技術が必要です。react-virtualized、react-window、react-virtual はこの課題を解決する代表的なライブラリですが、設計思想と使い方が大きく異なります。
react-virtualized は、リストやグリッドのための完成されたコンポーネントを提供します。
<List> や <Grid> を使います。// react-virtualized: 完成されたコンポーネントを使用
import { List } from 'react-virtualized';
<List
width={600}
height={400}
rowCount={1000}
rowRenderer={({ index, style }) => (
<div style={style}>Row {index}</div>
)}
/>
react-window もコンポーネントを提供しますが、より軽量でシンプルです。
react-virtualized の問題点を解消するために作られました。// react-window: 軽量なコンポーネントを使用
import { FixedSizeList } from 'react-window';
<FixedSizeList
width={600}
height={400}
itemCount={1000}
itemSize={35}
>
{({ index, style }) => (
<div style={style}>Row {index}</div>
)}
</FixedSizeList>
react-virtual は、UI を提供しない「ヘッドレス」なフックです。
@tanstack/react-virtual が正式です。// react-virtual: フックで計測だけ行う(非推奨パッケージ)
import { useVirtual } from 'react-virtual';
const virtual = useVirtual({
size: 1000,
parentRef,
estimateSize: () => 35,
});
return (
<div ref={parentRef}>
<div style={{ height: virtual.getTotalSize() }}>
{virtual.virtualItems.map(item => (
<div key={item.key} style={{ transform: `translateY(${item.start}px)` }}>
Row {item.index}
</div>
))}
</div>
</div>
);
ライブラリの選び方は、プロジェクトの柔軟性要件によります。
react-virtualized は設定項目が多く、初期コストが高いです。古い設計のため、現代の React 機能(例:Hooks)との相性が良くありません。react-window は必要十分な機能に絞られており、導入が簡単です。標準的なユースケースならこれで十分です。react-virtual は DOM 構造を自分で組むため、自由なレイアウトが可能です。しかし、その分手間がかかります。💡 ヒント:
react-virtualパッケージは現在メンテナンスされていません。同等の機能が必要な場合は@tanstack/react-virtualを使用してください。
アイテムの高さが一定でない場合(例:チャットログ、コメント欄)、各ライブラリの対応は以下の通りです。
react-virtualized は CellMeasurer と言うコンポーネントで計測します。
// react-virtualized: CellMeasurer で計測
<CellMeasurerCache defaultHeight={100}>
<List
rowRenderer={({ index, style, parent }) => (
<CellMeasurer key={index} cache={cache} parent={parent} index={index}>
{({ measure, height }) => (
<div style={style} onLoad={measure}>
Content {index}
</div>
)}
</CellMeasurer>
)}
/>
</CellMeasurerCache>
react-window は VariableSizeList コンポーネントを使います。
resetAfterIndex で通知します。// react-window: 可変サイズリスト
import { VariableSizeList } from 'react-window';
<VariableSizeList
itemCount={1000}
itemSize={index => heights[index]}
onItemsRendered={({ visibleStopIndex }) => {
// 必要に応じてサイズ更新を通知
}}
>
{({ index, style }) => (
<div style={style}>Row {index}</div>
)}
</VariableSizeList>
react-virtual はフック内でサイズを推定し、必要に応じて更新します。
// react-virtual: 推定サイズと計測
const virtual = useVirtual({
size: rows.length,
parentRef,
estimateSize: () => 50, // 推定値
measureSize: (el) => el.getBoundingClientRect().height, // 実測ロジック
});
この点が最も重要な選定基準になります。
react-virtualized は事実上のレガシーです。
react-window への移行を公式に推奨しています。react-window は安定しており、広く使われています。
react-virtual はパッケージ名として非推奨です。
@tanstack/react-virtual へ引き継がれました。| 特徴 | react-virtualized | react-window | react-virtual |
|---|---|---|---|
| 提供形態 | 完成コンポーネント | 軽量コンポーネント | ヘッドレスフック |
| 保守状況 | レガシー(移行推奨) | 安定・維持中 | 非推奨(TanStack へ) |
| API 難易度 | 高い(複雑) | 低い(シンプル) | 中(自作要素あり) |
| 柔軟性 | 低い | 中 | 高い |
| 推奨度 | ❌ 新規採用非推奨 | ⭕ 標準的な選択 | ⚠️ パッケージ名に注意 |
react-window を第一選択としてください。
@tanstack/react-virtual (react-virtual の後継)を検討するのは以下の場合です。
react-virtualized は使わないでください。
仮想化ライブラリの選択は、パフォーマンスと保守性のバランスです。標準的な道を選ぶなら react-window、特殊な制御が必要なら @tanstack/react-virtual、これが現代の正しい選び方です。
このパッケージ名は非推奨であり、代わりに @tanstack/react-virtual を使用すべきです。フックを使ってレンダリングロジックを完全に制御したい場合に適しています。フレームワークに依存しないコアロジックが必要なら、新しい方のパッケージを検討してください。
既存のレガシープロジェクトを維持する場合を除き、新しいプロジェクトでの使用は推奨しません。作者自身によって react-window への移行が勧められており、バンドルサイズが大きく API も複雑です。維持コストがかかるため、新規採用は避けるべきです。
React コンポーネントとして手軽に仮想化リストを実装したい場合に最適です。作者が react-virtualized の後継として設計しており、API がシンプルで学習コストが低いです。標準的なリストやグリッド表示であれば、これが第一選択肢になります。
Table of Contents generated with DocToc

Hooks for virtualizing scrollable elements in React
Enjoy this library? Try the entire TanStack! React Query, React Table, React Charts, React Form