【実務・中級編】 仮想リストによる大量データ描画の最適化 – React実践ガイド

「1万件のリスト」を恐れるな。仮想リスト(Virtualization)で描画のボトルネックを物理的に消し去る技術

現場でReactを触っていると、必ず一度は壁にぶち当たる。「大量のリストデータをどうレンダリングするか」問題だ。

APIから数千、あるいは数万件のレコードが降ってきたとき、無防備に `map` で展開してDOMに流し込む……。これ、初心者の頃はやりがちだが、ブラウザにとっては「死刑宣告」に近い。DOMツリーが肥大化し、スクロールするたびにメインスレッドが悲鳴を上げ、ユーザー体験はガタガタになる。

今日は、この泥臭いパフォーマンス問題に終止符を打つ「仮想リスト(Virtualization)」という武器について、現場の視点で深掘りしていく。

—

なぜ「全件レンダリング」が悪なのか?

まず、ブラウザの気持ちになって考えてほしい。

1. DOM構築コスト: 1万個の `

` を生成すれば、それだけでメモリを大量に消費する。
2. Layout/Reflow: 画面内に見えていない要素であっても、ブラウザは「そこに何があるか」を計算し続ける必要がある。スクロールのたびに計算が走れば、フレームレートは落ちる。
3. Reactの調整(Reconciliation): Reactは仮想DOMで差分比較を行うが、リストの要素が増えればその比較コストも指数関数的に重くなる。

解決策はシンプルだ。「今、画面に見えているものだけをレンダリングする」。 これが仮想リストの真髄だ。

—

現代の最適解:`react-window` を使った実装

自前でスクロール位置を計算してDOMを出し入れする実装(いわゆる無限スクロールの発展版)は、エッジケースの嵐だ。ブラウザのスクロールバー挙動、キーボード操作、フォーカス管理……これらを自分で書くのは「車輪の再発明」どころか「地雷原の開拓」に近い。

だからこそ、React界隈では `react-window` がデファクトスタンダードとして君臨している。

実践:`react-window` によるリスト最適化

まずは、インストールから。
`npm install react-window`

以下は、1万件のデータを「表示領域分だけ」描画する、現場でそのまま使えるコード例だ。

import React from ‘react’;
import { FixedSizeList as List } from ‘react-window’;

// 1万件のダミーデータ生成
const data = Array.from({ length: 10000 }, (_, i) => `アイテム番号: ${i + 1}`);

// 各行を描画するコンポーネント(react-windowから渡される引数に注目)
const Row = ({ index, style }) => (


{data[index]}

);

const VirtualList = () => {
return (

{Row}

);
};

export default VirtualList;

—

現場で役立つ「ハマりどころ」とTips

コードは動いた。だが、実務レベルではもう少しだけ踏み込んだ調整が必要になる。

1. 「高さ」が可変の場合の絶望

`FixedSizeList` は各行の高さが一定であることを前提としている。もし「テキスト量によって行の高さが変わる」場合は、`VariableSizeList` を使う必要がある。ただし、パフォーマンスは少し落ちる。可能であれば、UI側で「高さ固定」をデザイン要件として握るのが、エンジニアとしては最も賢い立ち回りだ。

2. スクロールバーのカスタマイズ

`react-window` はDOMを動的に生成・破棄するため、標準的なCSSのスクロールバーカスタマイズが効きにくい場合がある。どうしても凝ったUIが必要なときは、`react-window` の外側にラッパーを置いて、コンテナのスタイルを制御する戦略を取ろう。

3. デバッグのコツ

ブラウザの「Elements」タブを見てほしい。リストの件数が1万件あっても、DOM上には表示されている数個(+バッファ)しか存在しないはずだ。この「DOMが存在しない」という事実こそが、パフォーマンスを担保する最大の証明だ。

—

最後に:完璧を求めすぎない勇気

仮想リストは魔法ではない。実装コストがかかるし、複雑なCSSレイアウトと組み合わせるとバグの温床になることもある。

「本当に仮想リストが必要か?」を常に自問自答してほしい。もしリストが100件程度なら、素直に `map` でレンダリングし、`React.memo` で各行の再レンダリングを制御する方が、コードの保守性は圧倒的に高い。

「パフォーマンス最適化は、ボトルネックが確認されてから行う」。 これが、僕らシニアエンジニアが現場で大切にしている鉄則だ。

それでも、数千件のデータを扱うダッシュボードやログビューアを任されたときは、この記事を思い出してほしい。その時、君の書くコードは、ブラウザを止めず、ユーザーに滑らかな体験を提供できるはずだ。

さて、次はどの技術の深淵を覗こうか? 現場からは以上だ。

コメント

タイトルとURLをコピーしました