SPAのHydrationとは何をしているのか

SPAにおけるHydrationの正体

ReactやVueの解説で必ず登場する「Hydration(ハイドレーション)」という言葉は、なんとなく「SSRのあとにJSが動く処理」と説明されがちです。しかしそれだけでは本質が分かりません。Hydrationは単なる初期化ではなく、HTMLとJavaScriptの状態を同期させる処理です。

結論から言うと、Hydrationとは「すでに存在しているDOMを再利用してアプリケーションを起動する」工程です。ここを理解すると、なぜSSRとSPAの組み合わせが難出なバグを生むのかが見えてきます。

まず前提:SPAは本来DOMを自分で作る

純粋なSPAでは、画面のHTMLはJavaScriptが生成します。

const root = document.getElementById("app");
root.innerHTML = "<h1>Hello</h1>";

ブラウザが受け取るHTMLにはコンテンツがありません。JavaScriptが実行されて初めてDOMが構築されます。つまり「DOMの所有者」は完全にJavaScriptです。

しかしSSRを導入すると状況が変わります。

SSRでは最初からHTMLが存在する

SSRでは、サーバが次のようなHTMLを返します。

<div id="app">
  <h1>Hello</h1>
</div>

ユーザは即座に内容を閲覧できます。ここまでは単なるサーバレンダリングです。しかしここから問題が始まります。

JavaScriptアプリケーションも同じ画面を生成しようとします。すると「DOMを作る」処理が重複します。

Hydrationが必要になる理由

もしSPAがそのまま動くと、次のようになります。

1. 既にあるHTMLを無視
2. JavaScriptが新しいDOMを作成
3. 古いDOMを破棄

これではSSRの意味がありません。描画がやり直され、画面がちらつきます。さらにイベントハンドラも失われます。

そこでフレームワークは「既存のDOMを再利用」します。これがHydrationです。

hydrateRoot(
  document.getElementById("app"),
  <App />
);

ここで行われるのは再描画ではありません。DOMと仮想DOMの差分確認です。

Hydrationで内部的に起きていること

Hydrationは次の工程で行われます。

  • 既存DOMを走査
  • 仮想DOMを構築
  • ノード一致確認
  • イベントリスナ接続
  • 状態同期

つまり、SSRが生成したHTMLに対して「これは自分が生成したものと同じか?」をチェックしています。

一致していれば、DOMを破棄せずにそのまま利用します。違っていれば再描画されます。

なぜHydrationが重いのか

Hydrationは単なる初期化ではありません。DOM全体の検証処理です。

SPA初期化:
JavaScript → DOM生成

Hydration:
DOM確認 → 仮想DOM生成 → 差分照合 → イベント接続

DOMの数が多いほど時間がかかります。特にスマートフォンでは顕著です。SSRで「表示が速いのに操作できるまで遅い」現象は、Hydrationが完了していない状態です。

Hydrationが終わるまで何が起きるか

Hydration中、ユーザは画面を見られますが操作できません。ボタンを押しても反応しない状態が発生します。これはバグではなく、イベントリスナがまだ接続されていないためです。

これを「インタラクション遅延」と呼びます。LighthouseのTime To Interactiveが遅くなる原因です。

よくある誤解

「SSRなら即操作できる」は誤りです。SSRが保証するのは表示速度だけです。操作可能になるのはHydration完了後です。

また、HydrationはSPAでも起きます。プリレンダリングを使っている場合、静的HTMLに対して同じ同期処理が行われます。

注意点

HydrationはHTMLとJavaScriptの内容が一致している前提で動きます。もしサーバとクライアントの出力が少しでも異なると、再描画が発生します。これがパフォーマンス低下の原因になります。

例:

const now = new Date();

サーバ時刻とブラウザ時刻が違うだけでDOMが一致しなくなります。

開発で気をつけるべきこと

  • ランダム値を描画に使わない
  • 日付を直接埋め込まない
  • ユーザ環境依存の表示をSSRに含めない

これらはすべてHydrationの不一致を引き起こします。

最後に

HydrationはSSRの「後処理」ではありません。SSRとSPAを接続する橋です。HTMLを見せるのがSSR、画面を操作可能にするのがHydrationです。

SSRを導入すると自動的にUXが良くなると思われがちですが、実際には「表示は速く、操作は遅い」という新しい問題が発生します。重要なのは描画速度ではなく、ユーザが操作できるタイミングです。

SSRとSPAを組み合わせるということは、2つのレンダリングシステムを同期させることです。Hydrationを理解せずにSSRを導入すると、表示速度の改善と引き換えに操作性を悪化させる可能性があります。SSRの評価はFirst Paintではなく、Hydration完了まで含めて行う必要があります。