🌻

Nuxtのユニバーサルレンダリングを知りたい

2024/03/05に公開

初めに

Nuxtのドキュメントでは、デフォルトのレンダリングモードとしてユニバーサルレンダリングが記載されていますが、このユニバーサルレンダリングについて今回はまとめたいと思います。

サーバー側レンダリングに似ています。
クライアント (ブラウザー) はバックグラウンドでサーバー上で実行される JavaScript コードを読み込みます。ブラウザーはそれを再度解釈し (したがってユニバーサル レンダリング)、Vue.js がドキュメントを制御して対話性を可能にします。

Nuxt Universal Rendering

https://nuxt.com/docs/guide/concepts/rendering#universal-rendering

理解の整理

それぞれのレンダリング手法やメカニズムをきちんと理解していたら、ドキュメント記載の説明文で、ユニバーサルレンダリングを理解できたでしょう。

CSR

クライアントサイドレンダリング。
JSによってクライアント側でHTMLを生成するレンダリング手法です。
初回リクエスト時にサーバーは空のHTMLと各画面を描画するために必要なJSファイルを送信します。
それらをブラウザがダウンロードすると、インターフェイスを作成するための命令を含むJavaScriptが実行されHTMLが生成されます。

SSR

サーバーサイドレンダリング。
その名の通りサーバーでHTMLを生成しブラウザに送信するレンダリング手法です。
あくまでレンダリング手法なので本当はこれだけの理解で正解だったのですが色々な記事を拝見したり開発をしているうちに下記のように誤解していきました..。

初回のリクエスト時のみ、サーバーにアクセスし、サーバ側が初回ページのHTMLをブラウザに返す。

従来のWebアプリが遷移時に毎回リクエストしていたのに対して、SSRでは初回アクセス時のみ、リクエストしている。

実はこれらは後述する"isomorphic"(アイソモルフィック)または "universal"(ユニバーサル)レンダリングと混同しています。
ですが現代のwebにおいてSSRとは、isomorphicuniversalが前提として隠れている、SPA+SSRを両立したアーキテクチャを指しているようです。
このあたりを頭の中でよしなに解釈していく必要があります。

MPA

マルチページアプリケーション。所謂、従来のWebアプリ。
ページ遷移ごとにブラウザがサーバーに新しいページのHTMLをリクエストします。
サーバーはリクエストされたページのHTMLを生成してレスポンスとして返します。
ブラウザは受け取ったHTMLをレンダリングし、ページ全体がリロードされます。
つまりレンダリング手法はSSR。

SPA

シングルページアプリケーション。RactやVueで開発する現代のWebアプリ。
レンダリング手法はCSR。

isomorphic、universal

直訳すると、「isomorphic = 同型」、「universal = 普遍的」です。
Vueの公式ドキュメントでは下記のように説明されています。

アプリケーションのコードの大部分がサーバーとクライアントの両方で実行されるという意味で、"isomorphic"(アイソモルフィック)または "universal"(ユニバーサル)であると考えることもできます。

https://ja.vuejs.org/guide/scaling-up/ssr#what-is-ssr

したがって、isomorphic・universalレンダリングとは、サーバーとクライアント両方でレンダリングする手法だとわかります。

ちなみにIsomorphic JavaScript或いはUniversal JavaScriptという用語が2015年の記事で言及されているようで、こちらはサーバーサイドやクライアントのコードをJavaScriptのコードで共通化させていこうという設計論です。

https://qiita.com/Ryusou/items/df00e5f89f2d0109a8c2#なぜuniversal-javascriptか

SPAはなぜリロードを発生せず遷移できるのか

ユーザーが異なるページに移動する際、SPAはサーバーから新しいHTMLページを要求するのではなく、必要なデータのみをAPI経由でフェッチし、クライアントサイドでビューを更新します。
このJavaScriptの介入により、ページのフルリロードを防ぎ、ビューを更新し、シームレスなSPA遷移を実現しています。
クライアントサイドでJavaScriptがページコンテンツを動的にレンダリング(=CSR)しているためリロードが発生しないというわけです。
このようにCSRを用いたリロードを伴わないSPAのページ遷移プロセスを、**クライアントサイドナビゲーション(CSN)**といいます。

後付けでCSN遷移プロセスを実現している

Nuxtのユニバーサルレンダリングでは、初期表示時SSRによりサーバーから生成された静的なHTMLに添付されたJavaScriptがクライアントサイドで実行されると、静的なHTMLに対して、動的な挙動を追加します。
Nuxtのドキュメントに記載がある通り、このように、初回ロード後にクライアントサイドで実行されるJavaScriptによって、静的なHTMLが、動的なアプリとして機能するようにするプロセスをハイドレーションと呼びます。

静的ページをブラウザ上でインタラクティブにすることを「ハイドレーション」と呼びます。

簡単にいうと、後付けで、インタラクティブな挙動を追加するプロセスです。
ハイドレーションが完了すると、クライアントサイドでのページ遷移を捕捉し、新しいページのデータを非同期にフェッチしてビューを更新することができるようになります。
つまり遷移時リロードが発生させない、SPAのCSN遷移プロセスとなります。
このハイドレーションプロセスによりNuxtアプリケーションはSPAのように動作し始めます。

まとめ

Nuxtのユニバーサルレンダリングとは初回のみSSRされたあと、それ以降はCSRさせる、SSRとCSRを組み合わせたレンダリング手法です。
メカニズムとしては、初期表示をSSRさせた後、ハイドレーションプロセスによってクライアントサイドで動的な挙動が追加され、その後のページ遷移がCSNになっていることがわかります。

Discussion