🚀 ニフティ’s Notion

🌞 【Webアプリ2024 #14】SPA(CSR), SSR, SSG, (PPR)

CSR(Client Side Rendering)

クライアント側のブラウザで JavaScript を実行することで、ページを表現・遷移する

  • 従来型MPAと比較して、データ取得し終わった部分から順次表示していくなど、柔軟な操作が可能
📖ページ表示方法
  1. クライアントはビルド済みの静的なHTMLやJavaScriptなどをストレージやサーバーから取得
    • HTMLの中身は基本空であり、ビルドしたJavaScriptを読み込むだけ
      • ページが1枚( index.html とか)のみ
  2. ページの表示・遷移などは取得したJavaScriptでDOMを経由して書き換える
    • 動的なデータ(例えばユーザー情報など)は Ajax , FetchAPI , Axios など でデータだけバックエンドのサーバーから取得するよう JavaScript で記述
      • 例えば React ライブラリ(後述)で 日付取得ボタン を押したら Axios で取得し、pタグに埋め込む
💭実装イメージ
  • HTMLに、クライアント側で動的に” root ”とかに JavaScript でHTML要素を加える
メリット
  • サーバーからページをすべて読み込む必要が無いので、初回の読み込み以降は高速
  • 静的なアセット( HTML , CSS , JavaScript )が置ければ機能する
  • サーバーサイドの言語が不要になり、すべてJavaScriptで記述できるため開発効率が上がる
デメリット
  • SEO で不利になりやすい
    • クローラーによっては、 JavaScript をサポートしていなかったり、サポートしていても時間が掛かる
      • 例: Google, Bingのクローラー
  • 最初は空の HTML で、ファイルのダウンロードからレンダリングまでが重い = 1ページ目の表示が遅い
  • JavaScript 前提なので、 JavaScript がオフのブラウザでは真っ白に見える
✨有名なCSR
  • React, Vue.js, Angular
SPA(Single-Page Application)

CSR では、 MPA とは異なり、ページ(HTML)は1つで、JavaScriptで表示内容を制御する。

これを MPA と比較して SPA(Single-Page Application) と呼ぶ。これは覚えておいてください。

SSR(Server Side Rendering)

サーバー側でデータ取得・HTMLレンダリングを行うことで、CSRの欠点を補うもの。

  • サーバー側で一度HTMLをレンダリングして返すことで、初期表示の遅さを克服
  • クライアント側で JavaScript をもう一度実行する( Hydration )ことでCSRと同じ状態にする
  • リクエストするたびにHTMLを生成する
📖ページ表示方法
  1. ユーザーはサーバーへリクエストを送り、サーバーは対応したページをレスポンスとして返却
    • 必要なデータがあれば、サーバーでAPIを叩きデータを取得した上でHTMLに埋め込む
  2. クライアント側で JavaScript をもう一度走らせることで動的な動作が行える状態にする
💭実装イメージ
  • Next.js では getServerSideProps を使うことでサーバーサイドで実行される
  • Svelte ではデフォルトでON
メリット
  • 初期レンダリングが CSR(SPA) より早い
  • レンダリング結果を返すので SEO に強い
  • データ取得時はAPIを裏で叩くことによるパフォーマンス向上
    • クライアントから叩くときよりデータの取得が早くできたり、クライアントのリクエスト数が減る
  • APIのエンドポイントを秘密にしたりできるので、セキュリティ向上
デメリット
  • サーバ側でのHTML生成が必要なため、 SSR 用のサーバーが必要になる
  • 表示完了から操作可能になるまでにタイムラグがある
    • 表示は返ってきたHTMLをそのまま表示するだけ
    • JavaScriptが必要な処理はHydrationの完了を待つ必要がある
有名なSSR
  • Next.js, Nuxt.js, SvelteKit, Remix

SSG(Static Site Generation)

ビルド時にAPIの情報などを取得して静的ファイルを作る。アクセス時はその静的ファイルを取得してページを表現

  • ビルド時にHTMLを生成し、リクエスト時はそれを使いまわす
📖ページ表示方法
  1. あらかじめ静的ファイルにビルドしておく
    • API先のデータなどはビルド時に取得し、埋め込まれる
  2. ユーザーはアクセス時、ビルドされた静的ファイルを取得しWebサイトを表現
💭実装イメージ
  • Next.js では getStaticProps などを読んでビルドする
メリット
  • アクセス時は静的ファイルが返るだけなので、レスポンスが非常に早い
  • 作成済のHTMLを返すので SEO に強い
デメリット
  • ビルド時に全ての情報を取得してビルドするので、コンテンツ量が増えるとビルド時間も増える
  • 頻繁に情報が更新されるサイトでは使うことが困難
    • APIが持ってこれるのはあくまでビルド時の状態
✨有名なSSG
  • Next.js, Nuxt, SvelteKit, Gatsby, Astro
ISR(Incremental Static Regeneration)

アクセスされた時に初めてSSGのビルドが走りサイトを生成する方法。

  1. ユーザーがページにアクセスする
  2. SSGのビルドが走る
  3. 生成結果をユーザーに返す
  4. 二回目以降はキャッシュされたビルド結果のHTMLが返される
  5. キャッシュが古くなったと見なされた場合、裏側でビルドが走り、最新のページになるようにアップデートする
メリット
  • SSGのビルド時間を考えなくていい
  • 新しい記事などを再配置することで更新できる
デメリット
  • キャッシュがかかる場合は更新ページを反映する時がテクニカルになる場合がある
✨有名なISR
  • Next.js

レンダリング使い分け

サーバ側とクライアント側のレンダリングは、用途に合わせて使い分ける

(Experimental) Partial Prerendering

部分的に動的なコンテンツと静的なコンテンツを使い分ける

  • 動的なコンテンツはSpinner とかにしておいて、ロード終わったら表示

Next.jsはすぐアップデートされるので、頭に入れておくと良さそう

ここではフロントエンドで主流なレンダリング手法について説明した。次に、これらのレンダリング手法を実装できるフレームワークについて説明する。