最終更新日: 2023年08月15日
レンダリングモード
Nuxtは異なるレンダリングモードをサポートしており、ユニバーサルレンダリング、クライアントサイドレンダリングだけでなく、ハイブリッドレンダリングやCDNエッジサーバー上でのアプリケーションのレンダリングも提供しています。
ブラウザとサーバーの両方がJavaScriptコードを解釈して、Vue.jsコンポーネントをHTML要素に変換できます。このステップを「レンダリング」と呼びます。Nuxtはユニバーサルレンダリングとクライアントサイドレンダリングの両方をサポートしています。これらのアプローチには利点と欠点がありますが、それらについて説明します。
デフォルトでは、Nuxtはユニバーサルレンダリングを使用して、より良いユーザーエクスペリエンス、パフォーマンス、および検索エンジンのインデックス化を提供しますが、1行の設定でレンダリングモードを切り替えることができます。
ユニバーサルレンダリング
ブラウザがユニバーサル(サーバーサイド + クライアントサイド)レンダリングが有効なURLをリクエストすると、サーバーは完全にレンダリングされたHTMLページをブラウザに返します。ページが事前に生成されてキャッシュされているか、リクエスト時にリアルタイムでレンダリングされているかにかかわらず、Nuxtはある時点でサーバー環境でJavaScript(Vue.js)コードを実行し、HTMLドキュメントを生成します。ユーザーはクライアントサイドレンダリングとは対照的に、アプリケーションのコンテンツをすぐに取得します。このステップは、PHPやRubyアプリケーションによって実行される従来のサーバーサイドレンダリングに似ています。
クライアントサイドレンダリングの利点であるダイナミックなインターフェースやページのトランジションを失わないようにするために、クライアント(ブラウザ)はHTMLドキュメントをダウンロードした後に、サーバーで実行されるJavaScriptコードをバックグラウンドで読み込みます。ブラウザは再度それを解釈します(したがってユニバーサルレンダリング)し、Vue.jsがドキュメントを制御し、対話的な機能を有効にします。これにより、サーバーサイドレンダリングの利点とクライアントサイドレンダリングの利点を組み合わせて、より優れたユーザーエクスペリエンスを提供します。
静的なウェブページを動的なものに変換する手法を「ハイドレーション」と呼びます。
ユニバーサルレンダリングにより、Nuxtアプリケーションはクイックなページ読み込み時間を提供しつつ、クライアントサイドレンダリングの利点を維持することができます。さらに、コンテンツがすでにHTMLドキュメントに含まれているため、クローラーがオーバーヘッドなしにインデックス化できます。
サーバーサイドレンダリングの欠点:
- 開発の制約サーバーとブラウザの環境は同じAPIを提供しないため、両方の環境でシームレスに動作するコードを書くのは難しいことがあります。幸いなことに、Nuxtはガイドラインと特定の変数を提供しており、コードがどちらの環境で実行されているかを判断するのに役立ちます。
- コストページをリアルタイムでレンダリングするためには、サーバーが稼働している必要があります。これにより、従来のサーバーと同様に、毎月のコストが発生します。ただし、ブラウザがクライアントサイドのナビゲーションを引き継ぐユニバーサルレンダリングにより、サーバーコールが大幅に削減されます。エッジサイドレンダリングを活用することでコスト削減が可能です。
サーバーサイドレンダリングの利点:
- パフォーマンスブラウザは静的コンテンツをJavaScriptによって生成されたコンテンツよりもはるかに速く表示できるため、ユーザーはページのコンテンツに直ちにアクセスできます。同時に、Nuxtはハイドレーションプロセスが行われる際にウェブアプリケーションの対話性を保持します。
- 検索エンジン最適化(SEO)ユニバーサルレンダリングはクラシックなサーバーアプリケーションとしてブラウザにページの全HTMLコンテンツを提供します。ウェブクローラーは直接ページのコンテンツをインデックスできるため、ユニバーサルレンダリングは迅速にインデックスしたいコンテンツには最適な選択肢です。
ユニバーサルレンダリングは非常に柔軟でほぼあらゆるユースケースに適しており、特にコンテンツに焦点を当てたウェブサイトに適しています。ブログ、マーケティングサイト、ポートフォリオ、eコマースサイト、マーケットプレイスなどが含まれます。
クライアントサイドレンダリング
デフォルトでは、従来のVue.jsアプリケーションはブラウザ(またはクライアント)でレンダリングされます。その後、Vue.jsは現在のインターフェースを作成するための指示を含むすべてのJavaScriptコードをブラウザがダウンロードして解析した後にHTML要素を生成します。
クライアントサイドレンダリングの利点
- 開発速度クライアントサイドのみで作業する場合、サーバーの互換性を心配する必要がなくなります。たとえば、windowオブジェクトのようなブラウザ専用のAPIを使用することがあります。
- コスト削減サーバーを実行することは、JavaScriptをサポートするプラットフォームで実行する必要があるため、インフラストラクチャのコストがかかります。クライアントのみのアプリケーションは、HTML、CSS、およびJavaScriptファイルがあれば、任意の静的サーバーでホストできます。
- オフライン利用コードが完全にブラウザで実行されるため、インターネットが利用できない場合でも、アプリケーションはスムーズに動作し続けることができます。
クライアントサイドレンダリングの欠点
- パフォーマンスユーザーは、ブラウザがJavaScriptファイルをダウンロード、解析、実行するのを待たなければなりません。ダウンロード部分にはネットワーク、解析および実行にはユーザーのデバイスによって時間がかかることがあり、ユーザーエクスペリエンスに影響を与える可能性があります。
- 検索エンジン最適化(SEO)クライアントサイドレンダリングで提供されるコンテンツのインデックス化と更新には、サーバー側でレンダリングされたHTMLドキュメントよりも時間がかかります。これは、前述のパフォーマンスの欠点と関連しています。検索エンジンのクローラーは、ページのインデックス化のためにインターフェースが完全にレンダリングされるのを最初の試行で待ちません。純粋なクライアントサイドレンダリングでは、コンテンツが表示されるまでおよび検索結果ページで更新されるまでに時間がかかる可能性があります。
クライアントサイドレンダリングは、インデックス化が必要でないか、ユーザーが頻繁に訪れる必要がある、非常にインタラクティブなウェブアプリケーションに適しています。ブラウザのキャッシュを活用して、SaaS、バックオフィスアプリケーション、オンラインゲームなど、後続の訪問時にダウンロードフェーズをスキップすることができます。
Nuxtでは、nuxt.config.ts
ファイルでクライアントサイドのみのレンダリングを有効にすることができます。
- ts
export default defineNuxtConfig({
ssr: false,
});
ハイブリッドレンダリング
例: 間違った例
ハイブリッドレンダリングは、ルートルールを使用して異なるキャッシュルールをルートごとに設定し、特定のURLへの新しいリクエストに対してサーバーがどのように応答するかを決定します。
以前は、Nuxtアプリケーションのすべてのルート/ページとサーバーは、同じレンダリングモード(ユニバーサルまたはクライアントサイド)を使用する必要がありました。しかし、さまざまなケースでは、一部のページをビルド時に生成し、他のページはクライアントサイドレンダリングを行う必要があります。例えば、コンテンツのウェブサイトに管理セクションがあるとします。すべてのコンテンツページは主に静的で一度だけ生成される必要がありますが、管理セクションは登録が必要であり、より動的なアプリケーションのように振る舞う必要があります。
Nuxt 3には、ルートルールとハイブリッドレンダリングのサポートが含まれています。ルートルールを使用すると、nuxtルートのグループに対してルールを定義し、レンダリングモードを変更したり、ルートに基づいてキャッシュ戦略を割り当てたりすることができます!
Nuxtサーバーは、自動的に対応するミドルウェアを登録し、Nitroキャッシュレイヤーを使用してルートをキャッシュハンドラーでラップします。
例:
- ts
export default defineNuxtConfig({
routeRules: {
// ホームページはビルド時に事前にレンダリングされます。
"/": { prerender: true },
// 製品ページはオンデマンドで生成され、バックグラウンドで再検証されます。
"/products/**": { swr: true },
// ブログ投稿はオンデマンドで1度生成され、次回のデプロイまで再生成されません。
"/blog/**": { isr: true },
// 管理ダッシュボードはクライアント側でのみレンダリングされます。
"/admin/**": { ssr: false },
// APIルートにCORSヘッダーを追加。
"/api/**": { cors: true },
// 過去のURLをリダイレクトする(リダイレクト設定)。
"/old-page": { redirect: "/new-page" },
},
});
使用できる異なるプロパティは以下の通りです:
- redirect: stringサーバーサイドのリダイレクトを定義します。
- ssr: booleanアプリケーションの一部のセクションに対してサーバーサイドレンダリングを無効にし、ssr: false を使用してSPAのみにします。
- cors: booleancors: true を使用すると、自動的にcorsヘッダーが追加されます。ヘッダーをオーバーライドして出力をカスタマイズすることもできます。
- headers: objectサイトの特定のセクションに特定のヘッダーを追加します。たとえば、アセットに対してヘッダーを設定することができます。
- swr: numberサーバーレスポンスにキャッシュヘッダーを追加し、設定可能なTTL(有効期限)でサーバーまたはリバースプロキシでキャッシュします。Nitroのnode-serverプリセットはフルレスポンスをキャッシュできます。TTLが切れた場合、キャッシュされたレスポンスが送信され、ページがバックグラウンドで再生成されます。
- isr: booleanswrと同様の動作ですが、これをサポートするプラットフォーム(現在はNetlifyまたはVercel)のCDNキャッシュにレスポンスを追加することができます。
- prerender: booleanビルド時にルートをプリレンダリングし、それらをビルドに静的アセットとして含めます。
- experimentalNoScripts: booleanサイトの特定のセクションで、NuxtスクリプトやJSリソースヒントのレンダリングを無効にします。
可能な限り、ルートルールはデプロイメントプラットフォームのネイティブルールに自動的に適用され、最適なパフォーマンスが得られます(現在はNetlifyとVercelがサポートされています)。
エッジサイドレンダリング
エッジサイドレンダリング(ESR)は、Nuxt 3で導入された強力な機能であり、Content Delivery Network(CDN)のエッジサーバーを介してNuxtアプリケーションのレンダリングをユーザーにより近い場所で行うことができます。ESRを活用することで、パフォーマンスの向上とレイテンシーの削減が実現され、より優れたユーザーエクスペリエンスが提供されます。
ESRにより、レンダリングプロセスはネットワークの「エッジ」、つまりCDNのエッジサーバーにプッシュされます。ESRは、実際のレンダリングモードよりもむしろデプロイメントの対象となります。
ページのリクエストが行われると、オリジナルのサーバーまで直接進む代わりに、最も近いエッジサーバーでリクエストがインターセプトされます。このサーバーはページのためのHTMLを生成し、それをユーザーに送信します。このプロセスにより、データが移動する物理的な距離が最小限に抑えられ、レイテンシーが低減し、ページの読み込みが高速化されます。
エッジサイドレンダリングは、Nuxt 3を支えるサーバーエンジンであるNitroのおかげで可能になります。NitroはNode.js、Deno、Cloudflare Workersなど、さまざまなプラットフォームに対応しています。
ESRを利用できる現在のプラットフォームは以下のとおりです:
- Cloudflare Pagesgitの統合とnuxt buildコマンドを使用してゼロ設定でESRを利用できます。
- LagonNITRO_PRESET=lagon npx nuxt buildコマンドを使用してESRを利用できます。
- Vercel Edge Functionsnuxt buildコマンドとNITRO_PRESET=vercel-edge環境変数を使用してESRを利用できます。
- Netlify Edge Functionsnuxt buildコマンドとNITRO_PRESET=netlify-edge環境変数を使用してESRを利用できます。
ESRを使用する場合、ハイブリッドレンダリングはルートルールとともに使用できることに注意してください。
上記に挙げたプラットフォームに展開されたオープンソースの例を探索できます:
- Nuxt Todos Edge:ユーザー認証、SSR、およびSQLiteを備えたタスク管理アプリケーションです。
- Atinotes:編集可能なウェブサイトで、ユニバーサルレンダリングが使用されています。