大規模リストのレンダリング問題
DOMノードを10,000個レンダリングするとパフォーマンスが急落する理由と、仮想化による解決方法を理解します。
「大規模リストのレンダリング問題」はCoddyKit上の無料React Academyレッスンです。 これはレッスン1/4です。 下記で完全なレッスンを無料で読むことができます。その後、ブラウザ内の組み込みコードエディタと24時間対応のAIチューターでハンズオン演習できます。 これはReact Academy学習パスの一部であり、ウェブとCoddyKitアプリ全体で進捗が同期されます。 React Academyコースには全4レッスンが含まれています。
10000 個の li 要素をレンダリングする
1 万個の項目からなる配列を map し、それぞれに li をレンダリングするとします。画面に一度に収まるのは数十個だけであっても、React は忠実に 10000 個の DOM ノードを作成します。
その大部分は画面外にあり見えませんが、ブラウザはそれらすべてを作成し、レイアウトし、維持しなければなりません。
大規模な DOM ツリーにおけるブラウザのレイアウトコスト
大規模な DOM ツリーには、ブラウザにとって実際のコストがかかります。レイアウト、スタイルの再計算、メモリ使用量はすべてノード数に応じて増加するため、巨大なリストでは初回レンダリングが遅くなり、メモリ使用量も膨らみます。
エンジンが数万個のノードを追跡してリフローしなければならないと、単純な操作でさえカクつくことがあります。
スクロールパフォーマンスの低下
巨大なリストで最も大きな負担を感じるのは、スクロール時です。コンテンツが移動すると、ブラウザは再描画し、レイアウトを再計算することがあります。ノードが多すぎると、フレームレートが滑らかな水準を下回ります。
その結果、どれだけアプリの他の部分が高速でも、インターフェースが反応しないように感じる、カクつきや遅延のあるスクロールになります。
DevTools でノード数を測定する
ブラウザの DevTools にある Memory パネルで、ページ上の DOM ノード数を確認して問題を裏付けることができます。数千個のノードを作成するリストは、ここにはっきりと表示されます。
項目を増やしてレンダリングするにつれてその数が膨らんでいく様子を確認すれば、DOM のサイズがボトルネックになっている具体的な証拠になります。
仮想化の概念
仮想化は windowing と呼ばれることもあり、リスト全体ではなく、現在表示されている項目と少量のバッファだけをレンダリングします。スクロールすると、表示範囲に入る項目がマウントされ、範囲外に出る項目がアンマウントされます。
これにより、データに何個の項目が含まれていても、DOM 上に存在する要素を少数に保てます。DOM のサイズをデータセットのサイズから切り離せるということです。
表示ウィンドウの計算
表示ウィンドウは、スクロール位置、コンテナの高さ、項目の高さから導き出されます。ビューポートの高さを項目の高さで割ると、画面に収まるおおよその行数がわかり、スクロールオフセットから該当する行がわかります。
ライブラリはこれらの値を使って、その時点で正確にどのスライスの項目をレンダリングするかを決定します。
react-virtualized と react-window と TanStack Virtual
windowing を実装するライブラリはいくつかあります。react-virtualized は機能が豊富ですが規模が大きく、react-window は同じ作者による、より小さく用途を絞った書き直しです。TanStack Virtual は現代的なヘッドレスの選択肢です。
ほとんどのリストでは、react-window はシンプルさとパフォーマンスのバランスに優れています。そのため、このコースでは react-window を中心に扱います。
仮想化が必要になる場合
仮想化の効果があるのは、リストが長く、おおむね数百行以上ある場合や、画像やネストされたコンポーネントによって各行が重い場合です。このようなケースでは、DOM のサイズが実際にパフォーマンスへ悪影響を及ぼします。
無限フィード、大規模なデータテーブル、チャット履歴は、windowing が任意ではなく不可欠になる典型的な場面です。
効果が見合わない場合
数十個程度の単純な項目からなる短いリストでは、仮想化を導入しても大きなメリットがないまま複雑さが増します。絶対位置指定や測定のオーバーヘッドによって、かえって全体のパフォーマンスが低下することさえあります。
windowing は本当に大きなデータセットに限定してください。小規模なデータセットでは、通常の map のほうがシンプルで、十分に高速です。
得られる効果
windowing を使うと、10 万個の項目からなるリストでも、DOM には表示中の少数の項目だけが保持されます。そのため、初回レンダリングが高速になり、メモリ使用量が低く抑えられ、スクロールも滑らかになります。
設定時に少し複雑さが増す代わりに、データ量に左右されないパフォーマンスが得られます。これが仮想化の核となる利点です。
クイックチェック: 仮想化するタイミング
仮想化を導入する価値があるタイミングを判断してください。
まとめ: 大規模なリストの問題
数千個の DOM ノードをレンダリングすると、レイアウトコスト、メモリ使用量、スクロール時のカクつきが増大します。このことは DevTools のノード数で確認できます。仮想化では、表示ウィンドウとバッファだけをレンダリングするため、DOM を小さく保てます。
react-window は、react-virtualized や TanStack Virtual と比べて、用途を絞った軽量な選択肢です。大規模または負荷の高いリストには使用し、短く単純なリストでは使用しないでください。
よくある質問
「大規模リストのレンダリング問題」レッスンは無料ですか?
はい。「大規模リストのレンダリング問題」の完全なテキストはこのウェブで無料で読めます。インタラクティブに演習し(組み込みコードエディタと24時間対応のAIチューター)、React Academyコースの残りをアンロックするには、CoddyKit PROにアップグレードしてください。 React Academyコースには全4レッスンが含まれています。
「大規模リストのレンダリング問題」で何を学びますか?
DOMノードを10,000個レンダリングするとパフォーマンスが急落する理由と、仮想化による解決方法を理解します。 ブラウザで直接実行するハンズオンコードでReact Academyを演習し、24時間対応のAIチューターがレッスンを進める中での質問に答えます。
React Academyを始めるのに経験は必要ですか?
事前経験は必要ありません。CoddyKitのReact Academyは初級者から上級者向けに構成されているため、ここから始めるか最初から始めて、自分のペースで進むことができます。 これはレッスン1/4です。
「大規模リストのレンダリング問題」レッスンにはどのくらい時間がかかりますか?
ほとんどのCoddyKitレッスンは約5~10分かかります。各レッスンはコンパクトでインタラクティブなので、着実に進歩し、ウェブとアプリ全体で正確に前回の場所から再開できます。
このReact Academyレッスンでコードを書いて実行できますか?
はい。すべてのReact Academyレッスンに組み込みコードエディタが含まれているため、ブラウザでリアルコードを書いて実行し、即座のAIフィードバックを取得できます。ローカル設定は不要です。