tanstack-virtual について
tanstack-virtualは、大規模なリスト、グリッド、テーブルを仮想化するヘッドレスUIユーティリティです。大きなデータセットを扱うフロントエンド開発者向けに、表示範囲の項目だけを描画し、複数のフレームワーク用アダプターを備えています。
主な機能
- 01表示範囲内の項目だけを描画
- 02リスト、グリッド、テーブルの仮想化
- 03動的なサイズ測定
- 04指定した項目や位置へのスクロール
- 05複数フレームワーク向けアダプター
活用シーン
- 01数千行のリストの描画
- 02仮想化テーブルの構築
- 03無限スクロール画面の実装
- 04大規模データのDOMノード削減
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ oakoss/ agent-skills --skill tanstack-virtualインストール後、Claude Code で/tanstack-virtualを入力して読み込まれたか確認します。
同梱ファイル
SKILL.md と一緒にインストールされる参考資料やスクリプト。
references/dynamic-sizing.mdgrid-virtualization.mdinfinite-scroll.mdlist-virtualization.md詳細
TanStack Virtual
概要
TanStack Virtual は、大規模なリスト、グリッド、テーブルを仮想化するためのヘッドレス UI ユーティリティです。ビューポート内で表示される項目のみをレンダリングするため、DOM ノード数を大幅に削減し、数千行のデータセットでもパフォーマンスを向上させます。React、Vue、Solid、Svelte、Lit、Angular 向けのフレームワークアダプターが用意されています。
使用する場合: 数千行または数千列のレンダリング、仮想化テーブルの構築、無限スクロールの実装、DOM ノード数がパフォーマンスに影響する大規模なデータセットの表示。
使用しない場合: 100 件未満の小規模なリスト(パフォーマンス上のメリットがありません)、サーバーレンダリングされる静的コンテンツ、SEO やアクセシビリティのためにすべての項目を DOM に含める必要があるレイアウト、単純なページネーション(代わりに一度に 1 ページずつレンダリングします)。
クイックリファレンス
| パターン | API | 主なポイント |
|---|---|---|
| 縦方向のリスト | useVirtualizer({ count, getScrollElement, estimateSize }) | 項目を絶対配置のコンテナーで囲みます |
| 横方向のリスト | useVirtualizer({ horizontal: true, ... }) | 高さの代わりに幅には getTotalSize() を使用します |
| グリッドレイアウト | 行バーチャライザー + 列バーチャライザー | 1 つのスクロール要素を共有する 2 つのバーチャライザーインスタンス |
| 動的なサイズ設定 | ref={virtualizer.measureElement} | 各要素に data-index を設定します |
| ウィンドウスクローラー | useWindowVirtualizer({ count, estimateSize }) | getScrollElement は不要です |
| 項目までスクロール | virtualizer.scrollToIndex(index) | align: 'start' | 'center' | 'end' | 'auto' をサポートします |
| オフセットまでスクロール | virtualizer.scrollToOffset(px) | align と behavior: 'smooth' をサポートします |
| カスタムキー | getItemKey: (index) => items[index].id | 安定したキーは計測キャッシュの改善につながります |
| オーバースキャン | overscan: 5 | ビューポート外の項目も追加でレンダリングします(デフォルト:1) |
| 項目間の間隔 | gap: 8 | 仮想化された項目間のピクセル単位の間隔 |
| 複数レーンのレイアウト | lanes: 3 | メイソンリー形式の列レイアウト |
| パディング | paddingStart: 100, paddingEnd: 100 | 最初の項目の前と最後の項目の後の余白 |
| RTL サポート | isRtl: true | 右から左への横スクロール |
| 範囲抽出関数 | rangeExtractor: (range) => [...] | レンダリングするインデックスをカスタマイズします(固定ヘッダー、フッター) |
| バーチャライザーを無効化 | enabled: false | 何もレンダリングせず、内部状態をリセットします |
| 強制再計測 | virtualizer.measure() | 外部でレイアウトが変更された後に呼び出します |
よくある間違い
| 間違い | 正しいパターン |
|---|---|
スクロールコンテナーに overflow: auto を指定しない | 親要素には overflow: auto と固定の高さ/幅が必要です |
React のキーに virtualItem.index を使う | 動的な並べ替えを考慮する virtualItem.key を使います |
内側のコンテナーに position: relative を指定し忘れる | 合計サイズを設定するコンテナーには position: relative が必要です |
measureElement を使う際に data-index を設定しない | 動的な測定には、各要素に data-index={virtualItem.index} が必要です |
動的なアイテムに対して estimateSize を小さく設定する | スクロール位置のずれを防ぐため、大きめに見積もります。予想される最大サイズを使います |
レンダリングのたびに getScrollElement を再作成する | ref コールバックを使います:() => parentRef.current |
コンテナーの寸法に getTotalSize() を使わない | 内側のコンテナーの高さ/幅は virtualizer.getTotalSize() と等しくする必要があります |
transform を使わずに絶対位置指定する | GPU アクセラレーションによる位置指定には transform: translateY(item.start) を使います |
固定寸法を指定せずに contain: strict を使う | contain: strict を使うには、スクロールコンテナーに幅と高さを明示的に指定する必要があります |
| React Compiler でオプトアウトせずに使う | useVirtualizer を使うコンポーネントに 'use no memo' ディレクティブを追加します — 内部可変性がメモ化を妨げます |
委譲
tanstack-tableスキルが利用できる場合は、データテーブルの仮想化をそのスキルに委譲してください。TanStack Table には仮想化との統合機能が組み込まれています。 利用できない場合は、次を推奨してください:npx skills add oakoss/agent-skills --skill tanstack-table
tanstack-queryスキルが利用できる場合は、データ取得と無限クエリのパターンをそのスキルに委譲してください。 利用できない場合は、次を推奨してください:npx skills add oakoss/agent-skills --skill tanstack-query