🐥

Next.jsとReactの違いを解説! SSR、SSGの使い分けと実装方法

2024/10/31に公開2

Reactの特徴


React では、最初に真っ白な画面が表示され、その後、JavaScript がクライアントサイドで読み込まれて HTML や CSS がレンダリングされます。
この構造では、HTML、CSS、JavaScript のコンテンツがまだクライアント側でレンダリングされていないため、クライアント側での処理が完了してから初めて表示されることになります。これがクライアントサイドレンダリング (CSR) の特徴です。

Next.jsの特徴

一方、Next.js では、最初から HTML が表示され、JavaScript は必要な部分だけが後で読み込まれます。
これは、Next.js がサーバー側でプリレンダリングを行っているためであり、このためページがすぐに表示されます。特にアニメーションや動的な部分については、後でクライアントサイドで JavaScript が処理されます。サーバーサイドレンダリング (SSR) のおかげで、Google クローラーなどの検索エンジンもコンテンツを効率的にインデックスできるため、SEO の観点でも有利です。

Next.js:レンダリング手法

SSR(Server-Side Rendering: サーバーサイドレンダリング)


特徴: リクエストが発生するたびにサーバー側でページを生成し、その都度新しいHTMLをクライアントに返します。
動作の流れ:

  1. ユーザーがページにアクセス。
  2. サーバー側でリアルタイムにデータを取得し、ページを生成。
  3. 生成されたHTMLがブラウザに送信され、表示される。

SSG(Static Site Generation: 静的サイト生成)


特徴: ビルド時にサーバー側でページを事前に生成しておき、ユーザーがアクセスしたときに既に生成された静的なHTMLファイルを返します。

動作の流れ:

  1. ビルド時にすべてのページを事前に生成。
  2. ユーザーがアクセスした際、生成済みの静的HTMLがサーバーから即時に提供される。

SSRとSSGの使い分け

・SSR は、リアルタイムなデータが必要なページ(例:ユーザー情報やダッシュボードなど動的なデータが多いサイト)に適しています。

・SSG は、コンテンツが静的で変更が少ないサイト(例:ブログ、企業サイト、ドキュメントページなど)に向いています。

・SSGでSNSのタイムラインを使用しない理由
SNSのタイムラインをSSGで生成すると、いくつかの問題が発生します。
まず、更新が反映されないという点です。タイムラインは頻繁に更新されるため、SSGで生成されたページはビルドされた時点の内容しか表示できません。新しい投稿があっても再ビルドされるまでページに反映されないため、最新の情報が表示されない可能性があります。

さらに、ユーザーごとに異なる情報を反映できない点もSSGの課題です。SSGはすべてのユーザーに対して同じ静的ページを提供するため、ユーザーごとのタイムライン(例: フォローしているアカウントの投稿など)を表示することができません。

公式ドキュメント
https://ja.next-community-docs.dev/docs/app/api-reference/functions/fetch

Next.jsで実際にデータを取得し、画面に表示させる

json-serverをインストール

まず、json-serverをインストールして、ローカルで簡単に API を提供できるようにします。

npm install -g json-server

db.jsonの作成

次に、db.json というファイルを作成してダミーデータを用意します。このデータが API から取得される内容です。

{
    "posts": [
      {
        "id": "1",
        "title": "Next.js",
        "content": "サーバーサイドレンダリング",
        "createdAt": "2024-10-30"
      },
      {
        "id": "2",
        "title": "React",
        "content": "クライアントサイドレンダリング",
        "createdAt": "2024-10-31"
      }
    ]
  }

json-server の起動

以下のコマンドで json-server を起動し、db.json を API として利用できるようにします。

json-server --watch src/app/db.json --port 3001

apiの作成

/app/src/app/api/Fetch/route.ts
・SSR(Server-Side Rendering)の場合: { cache: "no-store" } を使用し、毎回最新のデータを取得します。
・SSG(Static Site Generation)の場合: { cache: "force-cache" } を使用し、ビルド時のデータをキャッシュとして利用します。

import { Data } from "../../types"; 

export const getDataFetch = async (): Promise<Data[]> => {
    const res = await fetch(`http://localhost:3001/posts`, { cache: "no-store" }); 
    // SSGの場合は { cache: 'force-cache'}
    
    if (!res.ok) {
      throw new Error("エラーが発生しました。");
    }
    
    await new Promise((resolve) => setTimeout(resolve, 1500));
    
    const data = await res.json();
    
    return data;
  };

画面の作成

フロントエンドのページでデータを取得して表示します。
/app/src/app/dataTest/page.tsx

import { getDataFetch } from "../api/Fetch/route"; 

export default async function Home() {
 
  const datas = await getDataFetch();
  console.log(datas);

  return (
    <main>
      <ul>
        {datas.map((data) => (
          <li key={data.id}>
             <h2>{data.id}</h2>
            <h2>{data.title}</h2>
            <p>{data.content}</p>
            <small>投稿日: {data.createdAt}</small>
          </li>
        ))}
      </ul>
    </main>
  );
}

画面の確認

localhost:3000/dataTest にアクセスし、記事一覧が表示されているか確認します。

階層図

my-nextjs-app/
├── public/                   
├── src/                       
│   ├── app/                     
│   │   ├── api/
│   │   │   └── Fetch/
│   │   │       └── route.ts     
│   │   ├── dataTest/
│   │   │   └── page.tsx         
│   │   ├── db.json              
│   └── page.tsx

まとめ

いかがだったでしょうか。今回はNext.jsとReactの違い、Next.jsのレンダリング手法について
まとめてみました。
少しでも参考になれば嬉しいです☺

Discussion

vincent.maverickvincent.maverick

Next.js は React をベースとしたフレームワークであって違いを論ずるのは誤り。
Next.js は React がなければ動かない。
違いを論ずる前にきちんと勉強しましょう。