
Hydration(ハイドレーション)は、SSRやSSGによってサーバ側で生成された静的HTMLに対し、クライアント側でJavaScriptを実行してイベントハンドラや状態管理を後付けし、ボタン・フォーム・モーダルなどをインタラクティブに動作させる処理を指します。Reactなら ReactDOM.hydrateRoot、Vueなら createSSRApp().mount() がその役目を担います。「水を与えて生き返らせる」という比喩から命名されており、SSRと組み合わせて使うことが前提です。
この記事の目次
- Hydrationの内部動作
- Hydrationが抱える課題
- Hydrationの改善アプローチ
- SSR・CSRとの関係整理
- まとめ
Hydrationの内部動作

Hydrationの処理は4ステップで進みます。まずブラウザはサーバから完成形のHTMLを受け取り、即座にDOMツリーが構築されて画面が表示されます。ここまでは静的なページと変わらず、ユーザーは早い段階で本文を読み始められます。その後、別便でダウンロードされたJavaScriptバンドルが評価され始め、Reactなどのフレームワークが起動します。
次にフレームワークはサーバが埋め込んだ初期状態(dehydrated stateと呼ばれるJSONブロブ)を読み、Virtual DOMをサーバ側と同じ形で組み立て、DOMとの対応関係を結びます。最後に各要素にイベントハンドラを取り付けることで、クリック・入力・スクロール等のインタラクションが動き始めます。この瞬間からSSRページは「ただのHTML」ではなく「Reactアプリ」として振る舞い、状態管理・ルーティング・データフェッチが有効になります。Hydrationが完了するまでの間、画面は見えていても操作できない時間帯が生じるため、TTI(Time To Interactive)の悪化要因として議論されます。
Hydrationが抱える課題

Hydrationには構造的なコストが伴います。まずサーバとクライアントの双方でコンポーネントツリーを構築する「二重レンダリング」が起き、サーバはHTMLを文字列で組み立て、ブラウザは同じツリーをVirtual DOM上で組み立て直すことで計算が重複します。結果としてTTI(操作可能になるまでの時間)が長くなり、特にローエンド端末や3G回線では「画面は見えるのに押せない」状態が数秒続くことがあります。
もう一つの問題はサーバとクライアントの不一致です。サーバ側でDate.now()やMath.random()のような非決定的な値を使うと、Hydration時にDOMが食い違って「Hydration error」が発生し、Reactは差分の安全側に倒すために再描画を強要します。また、ページに必要のないコンポーネントまでJSバンドルに含まれていると、未使用コードのHydrationでメモリを浪費します。これらの課題から、後述のIslands ArchitectureやPartial Hydration、Streaming SSRといった改善策が次々提案されています。
Hydrationの改善アプローチ

Hydrationコストを軽くするアプローチは大きく3系統あります。1つ目はPartial Hydrationで、ページ全体ではなく対話が必要なコンポーネントだけを選んでHydrate対象にする考え方です。Astroのclient:loadディレクティブや、ReactのServer Componentsを使うと、「画像とテキスト中心の領域はサーバHTMLのまま、コメント欄やカートだけJS化」という設計が可能になります。
2つ目はLazy Hydrationで、画面外の要素や使われるまで時間が空くUIをIntersection Observerで遅延起動します。3つ目はResumable Hydrationで、QwikというフレームワークがDOMとシリアライズ済み状態を見てイベントが発生した瞬間だけ該当ハンドラを評価する方式を提唱しています。Resumableは「Hydrationそのものを行わない」極論的な改善で、初回ロードのJSコストを劇的に減らせる代わりに、状態のシリアライズ設計が複雑になるトレードオフがあります。
SSR・CSRとの関係整理

HydrationはSSR/SSGとCSRの橋渡しを担う処理です。純CSRなら最初から空HTMLとJSだけなので二重評価はありませんが、SEOも初回表示も犠牲になります。SSRで完成HTMLを返し、その後Hydrationでインタラクティブ化することで、SEOの強さとCSRの操作性の両方を取りに行くのがモダンフレームワークの基本戦略です。Next.jsの「getServerSideProps + ReactDOM.hydrateRoot」、Nuxtの「universal mode」がその典型例です。
Hydrationは「便利だがタダではない」処理だと押さえておくのが大事です。数十KBのJSバンドルで済む小規模サイトなら無視できますが、数百KB〜数MBの規模になるとローエンド端末でのTTIが数秒〜十数秒に伸び、ユーザー離脱に直結します。そこで近年は「Hydrationする量を減らす」方向(Server ComponentsやIslands Architecture)と、「Hydrationをやらない」方向(Qwik、Marko 6)が並走しており、Webアプリの基盤技術として最もホットな研究領域の一つになっています。
まとめ
HydrationはSSR/SSGで返された静的HTMLにJavaScriptを後付けし、ボタンやフォームを動かせる状態へ「水やり」する処理です。二重レンダリングのコストとTTI悪化という弱点があるため、Partial・Lazy・Resumableといった改善が活発に進んでおり、IslandsやServer Componentsとあわせてモダンフロントエンドの設計を更新し続けています。
※本記事はIT用語辞典の手書きドラフトです。公開前に最新情報・出典を確認のうえ加筆修正してください。

コメント