1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

[Next.js] SSR, CSR, SSG, ISR とは??

Posted at

はじめに

Next.jsの勉強を始めて SSR, CSR, SSG, ISR の違いをしっかりと理解したいと思いまとめることにしました。

SSR(Server Side Rendering)

クライアントからのリクエストがあった際に、サーバーはサーバー側でJavaScriptを実行して表示するHTMLをレンダリング(生成)します。そして、完全にレンダリングされたHTMLをクライアントに送信します。

CSRとの違いは、ブラウザ側の仕事量です。CSRでは、クライアント側が「JavaScriptを実行して表示するHTMLを生成する」という仕事がありましたが、SSRではHTMLを生成する仕事はサーバー側にある為、ブラウザは返ってきたHTMLを表示するのみの仕事になります。

メリット

  • 常に最新のデータを表示できます
  • サーバ側で必要なページのみを生成し、ブラウザはそれを表示するだけなのでページが表示されるまでの速度が早い

デメリット

  • ページ遷移の度にサーバーへの通信が発生する

実装
Next.jsではデフォルトでSSR

// app/page.js
async function getServerSideData() {
  // サーバーサイドでのデータ取得
  const res = await fetch('https://api.example.com/data', { cache: 'no-store' }); //SSRではキャッシュを無効化することが多い
  if (!res.ok) {
    throw new Error('Failed to fetch data');
  }
  return res.json();
}

export default async function Page() {
  const data = await getServerSideData();
  console.log('--- SSR: Data fetched on the server ---');
  return (
    <div>
      <h1>Server-Side Rendered Page</h1>
      <p>{data.message}</p>
    </div>
  );
}

CSR(Client Side Rendering)

CSRは、初期リクエストではJavaScriptバンドルと最小限のHTMLをサーバーから取得し、その後ブラウザ上でJavaScriptを実行してAPIからデータを取得➡DOMを構築➡ページを表示するやり方です。

メリット

  • ページ遷移が早い:初回ロード後は、必要なデータのみを取得して画面を更新するため、SPA(Single Page Application)のような感覚で高速なページ遷移が可能です

デメリット

  • 初回表示が遅い:JavaScriptのダウンロードと実行、APIからのデータ取得に時間がかかります

実装

// app/client-page.js
'use client'; // このディレクティブがCSRを有効にする

import { useState, useEffect } from 'react';

export default function ClientSidePage() {
  const [data, setData] = useState(null);
  const [loading, setLoading] = useState(true);

  useEffect(() => {
    console.log('--- CSR: Fetching data on the client ---');
    const fetchData = async () => {
      try {
        const res = await fetch('https://api.example.com/data');
        if (!res.ok) {
          throw new Error('Failed to fetch data');
        }
        const result = await res.json();
        setData(result.message);
      } catch (error) {
        console.error("Error fetching data:", error);
      } finally {
        setLoading(false);
      }
    };

    fetchData();
  }, []); // 空の依存配列で、コンポーネントマウント時に一度だけ実行

  if (loading) {
    return <p>Loading data...</p>;
  }

  return (
    <div>
      <h1>Client-Side Rendered Page</h1>
      <p>{data}</p>
    </div>
  );
}

SSG(Static Site Generation)

SSGは、アプリケーションのビルド時に、すべてのページを事前にHTMLファイルとして生成する手法です。生成されたHTMLファイルは、CDN(Content Delivery Network)などを通じて高速に配信されます。

メリット

  • 静的ファイルとして配信されるため、CDNのキャッシュを最大限に活用できます
  • ビルド時に生成された静的なHTMLが配信されるため、リクエストごとにサーバーでの処理が不要です

デメリット

  • ページ数が多ければビルドに時間がかかります

実装

// app/static-page.js
async function getStaticData() {
  // ビルド時にデータが取得され、HTMLに埋め込まれる
  // デフォルトのfetchオプションは { cache: 'force-cache' }
  const res = await fetch('https://api.example.com/static-data');
  if (!res.ok) {
    throw new Error('Failed to fetch data');
  }
  return res.json();
}

export default async function StaticPage() {
  const data = await getStaticData();
  console.log('--- SSG: Data fetched at build time ---');
  return (
    <div>
      <h1>Static Site Generated Page</h1>
      <p>{data.message}</p>
    </div>
  );
}

ISR(Incremental Static Regeneration)

ISRは、SSGの高速性を維持しながら、コンテンツの更新を可能にする方法です。ビルド時にページを生成し、その後、指定した感覚(revalidate 秒)でバックグラウンドでページを再生成します。ユーザーからのリクエストがあった際に、最新のデータがあればそちらを、なければ古いデータを一時的に返します。

メリット

  • 常にリクエストごとにレンダリングするわけではないため、SSRよりサーバー負荷を抑えられます
  • 高速な配信を維持しつつ、定期的にコンテンツを更新できます

デメリット

  • revalidate の間隔によっては、変更がユーザーに反映されるまでにタイムラグが生じます
  • ISRであっても、ビルド時にはデータが固定されるため、ビルド後すぐに最新の情報が必要な場合は不向きです

実装

// app/revalidated-page.js
async function getRevalidatedData() {
  // 60秒ごとにバックグラウンドで再生成を試みる
  const res = await fetch('https://api.example.com/revalidate-data', {
    next: { revalidate: 60 } // 60秒ごとに再生成
  });
  if (!res.ok) {
    throw new Error('Failed to fetch data');
  }
  return res.json();
}

export default async function RevalidatedPage() {
  const data = await getRevalidatedData();
  console.log('--- ISR: Data fetched, with revalidation every 60s ---');
  return (
    <div>
      <h1>Incremental Static Regeneration Page</h1>
      <p>{data.message}</p>
    </div>
  );
}

まとめ

手法 レンダリングタイミング SEO 初期表示速度 サーバー負荷 データ鮮度 主な用途
SSR リクエストごと(サーバー) ログイン情報など動的なコンテンツ、SEO重視
CSR ブラウザ実行時(クライアント) インタラクティブなUI、管理画面
SSG ビルド時 ブログ、ドキュメント、マーケティングサイト
ISR ビルド時 & 定期再生成 更新頻度の低いブログ、ECサイトの商品情報
1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?