「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` で各行の再レンダリングを制御する方が、コードの保守性は圧倒的に高い。
「パフォーマンス最適化は、ボトルネックが確認されてから行う」。 これが、僕らシニアエンジニアが現場で大切にしている鉄則だ。
それでも、数千件のデータを扱うダッシュボードやログビューアを任されたときは、この記事を思い出してほしい。その時、君の書くコードは、ブラウザを止めず、ユーザーに滑らかな体験を提供できるはずだ。
さて、次はどの技術の深淵を覗こうか? 現場からは以上だ。

コメント