Amazon Web Services ブログ

Next.js Web アプリケーションにおける SSG とSSR の比較: 正しいレンダリングアプローチの選択

人気の React フレームワークである Next.js は、開発者がモダンな Web アプリケーションを構築する方法を変えました。Next.js は、Static Site Generation (SSG) や Server Side Rendering (SSR) といった強力な機能を提供し、アプリケーションのパフォーマンスとユーザー体験を最適化します。本記事では、SSG と SSR の主な違い、利点、いつどちらかを選択するか、それぞれのアプローチで AWS Amplify を使ってデプロイする方法を説明します。Amplify は、フロントエンドの Web やモバイル開発者が AWS 上でフルスタックのアプリケーションを簡単に構築、ホストできるようにする包括的なソリューションです。

Static Site Generation (SSG) とは?

Static Site Generation は、ビルド時に静的な HTML ファイルを生成します。アプリをビルドするたびに、全てのページが作成されます。ユーザーが Web サイトにアクセスするとこれらのファイルがユーザーに提供され、サーバーは余計な作業をする必要がなくなります。このアプローチは、ブログやドキュメントサイトのような、頻繁に変更されないコンテンツを持つ Web サイトに適しています。

SSG の利点

  • 速度: レンダリングされた HTML ファイルが直接提供されるため、ロード時間が短縮されます。
  • スケーラビリティ: 静的ファイルは CDN によって簡単に提供され、アプリケーションの能力を向上させ、グローバルなトラフィックを処理することができます。

Server Side Rendering (SSR) とは?

Server Side Rendering は、ユーザーがリクエストしたときに、サーバー上で各ページを生成します。SSR では、ページを事前にレンダリングするサーバーがあります。それは、変数を差し込むテンプレートのようなもので、サーバーはすべてのレンダリングを処理します。。これはリクエスト時に発生するので、ユーザがページをリクエストすると、サーバ側でレンダリングされたページを取得します。このレンダリングはすべてサーバーサイドで行われ、ブラウザで実行されることはありません。そのため、ページがすでにサーバでレンダリングされてクライアントに提供されるのを待っている SSG とは異なり、SSR はリクエストを受け取ったときにサーバでページをレンダリングします。SSR は、e コマースサイトやソーシャルメディアプラットフォームのような、頻繁に変更される動的またはパーソナライズされたコンテンツを持つ Web サイトに最適です。

SSR の利点

  • 一貫したユーザー体験: ユーザーは、その場で生成された最新のコンテンツを見ることができ、常に最新の情報を得ることができます。
  • パーソナライゼーション: SSR は、ユーザーの嗜好やその他の動的なデータに基づいて、ユニークなコンテンツを提供することができます。

SSG と SSR のどちらを選ぶべきか

  • コンテンツは頻繁に更新されていますか?コンテンツが頻繁に変更されない場合は、パフォーマンスとスケーラビリティを向上させるために SSG を選択する方が良いでしょう。動的なコンテンツの場合、SSR はユーザーに最新の情報を提供します。
  • あなたの Web サイトはインタラクティブなユーザー体験を提供しますか? SSR Web サイトはインタラクティブなユーザー体験を提供しますが、SSG Web サイトは CSR や SSR と組み合わされていない限り、動的コンテンツをほとんど含まない静的なサイトです。
  • ビルド時とランタイムのどちらにレンダリングコストをかけたいですか? ビルド時にレンダリングコストを発生させたい場合は SSG を、ランタイムに発生させたい場合は SSR を選択してください。
  • SEO 対策は必要ですか? SEO のための SSR と SSG の主な違いは、サーバーの応答時間だけです。

ビジネス要件を考慮する

SSG は優れた SEO 効果を提供しますが、SSRは 検索ランキングに重要な動的コンテンツとパーソナライゼーションをより良くサポートします。

  • ユーザー体験: ユーザーがリアルタイムのデータやパーソナライズされたコンテンツを必要としているかどうかを検討しましょう。もし必要であれば、SSR の方がよいでしょう。そうでない場合は、SSG の方がより低いサーバー要件でより高速な体験を提供します。
  • 最新データ: SSRページはユーザーからのリクエストごとにサーバー上で生成されるため、常に最新のデータを表示します。すべてのリクエストで、常に最新/最新の情報を得ることができます。

Next.js の SSG と SSR: 正しいレンダリングアプローチの選択

この記事では、Next.jsの2つのレンダリングアプローチ、SSGとSSRについて説明します。また、あなたのアプリケーションに最適なレンダリングアプローチを判断するためのコードベース例も紹介します。

Next.js は、n 個の動的生成ルートを生成する機能をサポートしています。コードベースの例では、過去数日間の Hacker News のトップ投稿を 100 件取得し、それらの ID をホームページにレンダリングします。

クリックすると、それぞれのページに投稿の詳細が表示されます。これらの各ページはまた、pages/[hackerNewsArticleId] のようなルートを持ちます。あなたは、そのテンプレートページが slug 指定で pages フォルダで利用可能であることを見ることができます。

この静的に生成されるパスのリストを定義するために getStaticPropsgetStaticPaths の 2 つの Next.js 関数を使います。

getStaticProps は、ビルド時にページをプリレンダリングし、Hacker News API から投稿情報のリストを取得し、その情報を getStaticPaths と同様にコンポーネントの props に渡します。

2番目の関数である getStaticPaths は動的ルーティングに非常に重要です。getStaticProps から ID のリストを受け取り、以下のようなパスオブジェクトのリストを作成します。

export async function getStaticPaths() { 
       return { 
             paths: [{ params: { id: '1' } }, { params: { id: '2' } }], 
             fallback: false, // can also be true or 'blocking' 
      } }

Next.js はこのパスのリストを取り込み、それぞれのパラメータに対して新しいページを生成します。また、個々のページにルーティングするために、プライマリコンポーネントに Hacker News ID をインジェストしてレンダリングするようにしました。動的にレンダリングされたコンポーネントページに行くと、再び getStaticProps メソッドを呼び出して Hacker News の詳細エンドポイントを呼び出し、投稿のタイトルや投票数などを取得していることがわかります。これはコンパイル時のブログ記事のスナップショットであることに注意してください。

SSG のアプローチ

GitHub リポジトリから、SSG Next.js アプリを Amplify にデプロイする方法を説明します。まずは、以下をクリックして、このプロジェクトを自分の環境にデプロイしてください。Amplify でのデプロイとホスティングの詳細はこちらを確認してください。

Connect to GitHub を選択し、aws-amplify-console を認証します。

Deploy App ページで、Create new role を選択します。

ロールを作成したら、Deploy App ページで既存のロールをリフレッシュし、作成したばかりのロールを選択します。Save and Deploy を選択します。

アプリのデプロイには 2 ~ 3 分かかります。ボックスが表示されたら、Continue をクリックします。その後、Amplify アプリがプロビジョニング、ビルド、デプロイの各段階に進むのを確認できます。

デプロイが完了すると、そのドメインでホストされている Web サイトにアクセスできるようになります。

ドメインを選択すると、Amplify アプリに移動し、SSG Next.js アプリが表示されます。

SSR のアプローチ

Next.js の Web アプリケーションを GitHub から直接 Amplify にデプロイする方法を見ていきましょう。

実は Amplify にデプロイするときに、すでに SSR ページをデプロイしています。Next.js のすごいところは、ビルド時に生成するページもあれば、SSR を利用して動的なデータをレンダリングするページもあることです。

特定のページで Server Side Rendering を使用するには、getServerSideProps という非同期関数をエクスポートします。この関数は、リクエストごとにサーバーから呼び出されます。

ホストされているリンクで、/ssr ルートに移動します(ie. https://main..amplifyapp.com/ssr). このようなページが表示されるはずです。

よくある問題

Next.js では、Create React App (CRA) や React Router といったライブラリを活用する、非常に人気のあるフロントエンド・フレームワークとは異なるパラダイム・シフトが必要です。

CRA は、React アプリケーションを作成するためのボイラープレート・プロジェクトを提供するスターターキットです。CRA は Client Side Rendering (CSR) を使用し、アプリケーションはブラウザでレンダリングされ、通常、ユーザーのインタラクションに基づいてネットワークリクエストを分割するのがベストプラクティスです。SSG と比較すると、すべてのデータを一度にロードしなければなりません。

  • Static Site Generation
    • 大規模な静的 Web サイトでは、ビルドやデータ取得にかかる時間をすべて顧客に渡す代わりに、サイトがビルドされるのを何時間も待つことになるかもしれません。静的ページの数が 2 倍になるたびに、ビルド時間も 2 倍になります。
      • 10,000 のアイテムがある e コマース・ Web サイトの場合、各アイテムのフェッチ/ビルドに約 1 秒かかるとすると、ビルドとデプロイに 3 時間近くかかることになります。
      • この場合、Incremental Static Regeneration (ISR) が適しています。これによって Web サイト全体を再構築することなく変更を加えることができます。
    • データ・フェッチ
      • 最近の Web 開発では、ユーザーの viewport (表示領域) を埋めるのに十分な API 呼び出しだけを行い、潜在的に後続のユーザーアクションのためのデータをプリフェッチすることがが推奨されることがよくあります。しかし、SSG では、 Web ページ全体と潜在的なユーザーのアクションをすべて入力するために必要なすべての API をコールする必要があります。
    • ページの更新
      • 例えば、複数のセクションがあるブログのページなど、 Web サイトのあるページが頻繁に更新される場合、SSG はひとつのページに含まれる変更のために、サイト全体を頻繁にリビルドす必要があるかもしれません。
      • その結果、SSG ページはビルド時に HTTP ヘッダやクエリパラメータのようなリクエストに直接アクセスすることができません。もしこれらにアクセスしたければ、SSG に加えてカスタムミドルウェアを書かなければなりません。
  • Server Side Rendering
    • レイテンシ
      • 生成プロセスにおいて、外部 API からのデータ取得のように、最終的にページの読み込み速度に影響を与える外部要因があります。API のレスポンスが遅ければ、ページ生成の読み込み時間は遅くなります。また、SSR はリクエストごとにページを生成するので、SSG に比べて遅くなります。
      • SSR のページでキャッシュを有効にし、読み込み時間速度を改善するには、getServerSideProps を呼び出すときに、追加の HTTP ヘッダ、Cache-Control を追加する必要があります。こちらを参照してください。キャッシュについてもっと学びたい場合は、こちらも参照ください。
    • スケーラビリティ
      • SSR はリクエストごとにサーバーがフロントエンドを処理し生成する必要があり、Web サイトが複雑なページを持ち、処理するエンドクライアントが多い場合、スケーラビリティが低く、速度も遅くなります。
      • SSR の 動的 HTMLは静的な CDN (例:CloudFront) によってキャッシュされることができず、サーバーとの往復時間が長くなり、ページをリクエストしてからサーバーによって最初のバイトが読み込まれるまでの時間 (TTFB: Time to First Byte) が遅くなります。
    • SEO
      • Google と Bing は、最新のレンダリングエンジンで同じChromium ベースのクローラーを活用すると発表しましたが、JavaScript は依然として検索エンジンがページを解析する能力を複雑にし、SEO ランクを下げる可能性があります。検索エンジンは JavaScriptファイルをダウンロードする必要があり、サイトの他の部分に移動する前にバンドル全体が読み込まれるのを待てない可能性があります。結局のところ、Google や Bing があなたのページをどのようにランク付けするかは不確実であり、クローラーを楽にすることは理にかなっていると言えるでしょう。

クリーンアップ

まとめ

SSG も SSR も、Next.js アプリケーションの種類によってそれぞれの利点があります。プロジェクトのコンテンツ頻度、SEO、ユーザー体験、開発の複雑さなどを理解することで、Next.js プロジェクトで SSG と SSR のどちらを使うべきか、十分な情報を得た上で決定することができます。最終的には、特定のユースケースと、パフォーマンス、スケーラビリティ、動的コンテンツのトレードオフ次第です。

まずは、Amplify Hosting を利用して、ユーザー認証機能付きの Next.js 13 Web アプリを構築してみてください。

著者について

Alexa Bio

Alexa Perlov

Alexa Perlov は、ニューヨークを拠点とするAmazon Web Services のソリューションアーキテクトです。メディアとエンターテインメントの戦略的アカウントのビジネス目標達成のために AWS を活用するサポートをしてます。技術トレーニングをリードし、幅広いクラウドドメインに焦点を当てたプロトタイプを開発しています。

Alexa Bio

Michael Tran

Michael Tran は Amazon Web Services のプロトタイピングアクセラレーションチームのソリューションアーキテクトです。技術的なガイダンスを提供し、AWS 上で可能なアートを示すことで顧客のイノベーションを支援しています。専門は AI/ML 分野におけるプロトタイプの構築。

本記事は、SSG vs SSR in Next.js Web Applications: Choosing the Right Rendering Approach を翻訳したものです。翻訳はソリューションアーキテクトの稲田大陸が担当しました。