- Virtual DOMは「速いDOM」ではない
- DOM操作はなぜ重いのか
- jQuery時代に起きていた問題
- Virtual DOMの発想
- なぜ差分検出が効くのか
- 「再レンダリング=遅い」という誤解
- なぜ手動最適化では解決できなかったのか
- パフォーマンスの本当の効果
- 注意点:Virtual DOMは万能ではない
- 最後に
Virtual DOMは「速いDOM」ではない
Reactが登場したとき、Virtual DOMは「DOM操作を高速化する技術」と説明されることが多くありました。
しかしこれは半分だけ正しく、半分は誤解です。
Virtual DOMはDOMを速くする技術ではありません。
ブラウザにDOM操作をさせる回数を減らすための仕組みです。
つまり問題はJavaScriptの処理速度ではなく、ブラウザの描画処理にありました。
ここを理解しないと、なぜVirtual DOMが必要だったのか見えてきません。
DOM操作はなぜ重いのか
JavaScriptの変数操作は非常に高速です。
let x = 0; x++;
この処理はほぼコストがありません。
一方、DOM操作は別物です。
document.getElementById("count").textContent = x;
この1行は単なる代入ではありません。
ブラウザ内部では次の処理が発生します。
- レンダーツリーの更新
- レイアウト再計算
- ペイント
つまりDOMはデータ構造ではなく、画面描画エンジンの一部です。
操作すると描画計算が始まります。
jQuery時代に起きていた問題
jQueryはDOM操作を簡単にしました。
しかし簡単になったことで、逆にDOMを頻繁に書き換えるコードが増えました。
例えば次のコードです。
for(let i=0;i<100;i++){ $("#list").append("<li>"+i+"</li>"); }
開発者の感覚では100回の文字列追加ですが、
ブラウザの視点では100回のレイアウト更新の可能性があります。
この状態をreflow地獄と呼びます。
スクロールがカクつく、入力が遅れるなどの原因になります。
つまり問題は
DOM操作が遅い
ではなく
DOM更新回数が多すぎるでした。
Virtual DOMの発想
Virtual DOMは、まず画面を書き換えません。
代わりにメモリ上のツリーを書き換えます。
流れは次の通りです。
1. 新しいUI状態を仮想ツリーに反映
2. 以前のツリーと比較(差分検出)
3. 必要なDOM変更だけ実行
これを差分更新(diffing)と呼びます。
つまりReactは「DOMを操作する」のではなく、
どのDOMを操作すべきかを計算しているのです。
なぜ差分検出が効くのか
通常、画面の大部分は変更されません。
例えばカウンターアプリでは、数字だけが変わります。
jQueryのアプローチ:
- 画面変更処理を人間が書く
Reactのアプローチ:
- UIを再構築し、変化点だけ適用
setCount(count + 1);
開発者はUI操作を書きません。
状態だけを書きます。
結果としてDOM更新は最小限になります。
「再レンダリング=遅い」という誤解
Reactでは状態変更のたびに再レンダリングが起きます。
これを不安に思う人もいますが、実際には問題ありません。
再レンダリングは「再描画」ではありません。
再計算です。
実際の描画は差分のみです。
つまり全UIを描き直しているわけではありません。
重いのは再レンダリングではなく、
不要なDOM更新です。
なぜ手動最適化では解決できなかったのか
「DOM更新を減らせばよいなら、手動で最適化すればいいのでは」と考えるかもしれません。
理論上は可能ですが、現実的ではありません。
UIが複雑になると次の問題が起きます。
- どの要素が変更されたか把握できない
- 変更漏れで画面が壊れる
- 修正で別のUIが壊れる
つまり最適化が人間の管理能力を超えました。
Virtual DOMは速度改善というより、複雑性の管理のための技術です。
パフォーマンスの本当の効果
Virtual DOMの最大の効果は平均速度の向上ではありません。
最悪ケースの回避です。
DOMを直接操作すると、特定条件で極端に遅くなります。
リスト、テーブル、フォームなどで顕著です。
差分更新により、最悪の遅延が起きにくくなりました。
結果として「常にそこそこ速い」UIになります。
注意点:Virtual DOMは万能ではない
Virtual DOMにも限界があります。
- 大量リスト描画
- アニメーション多用
- 低性能端末
これらでは依然として負荷が大きくなります。
そのため次のような技術が使われます。
- 仮想スクロール(windowing)
- メモ化(memoization)
- 部分レンダリング
つまりVirtual DOMは問題の終着点ではなく、
レンダリング最適化の一段階です。
最後に
Virtual DOMが解決したのはDOM速度ではありません。
人間がDOM更新を管理する問題です。
jQuery時代は、どのUIを更新するかを開発者が考えていました。
Reactでは、状態だけを考えればよくなります。
フロントエンドの進化は高速化の歴史に見えますが、
実際には「複雑さの制御」の歴史でもあります。
Virtual DOMはパフォーマンス最適化というより、
UIの整合性を保つための仕組みです。
その結果として速く見える、という順序を理解すると役割がはっきりします。