🙌

Next.js + TypeScript | CSR・SSR・SG・ISG・ISR・On Demand ISR の違いをコード付きで解説

2023/06/10に公開

概要

CSR・SSR・SG・ISG・ISR・On Demand ISR の違いをサンプルコード付きで解説

技術スタック

  • "microcms-js-sdk": "^2.5.0"
  • "next": "13.4.4"
  • "react": "18.2.0"
  • "react-dom": "18.2.0"

CSR

CSR = Client Side Rendering

ブラウザからのリクエストをトリガーに、ブラウザ上で JavaScript を実行し、API からデータを取得して、取得したデータをもとにクライアント側で HTML を生成する手法

React の useState と useEffect を使用することで利用可能

サンプルコード

pages / home / index.tsx

export const Home: NextPage = () => {
  return <HomeTemplate />
};

export default Home;

template / home / index.tsx

import { useEffect, useState } from "react";

import { Home } from "~/components/blocks/home";
import { microCmsClient } from "~/lib/micro-cms-client";

import type { NewsResponseObject } from "~/types/news-api";

export const HomeTemplate = () => {
  const [contents, setContents] = useState<NewsResponseObject[]>([]);

  useEffect(() => {
    (async () => {
      const data = await microCmsClient.get<{ contents: NewsResponseObject[] }>({ endpoint: "news" });
      setContents(data.contents);
    })();
  }, []);

  return <Home notifications={contents} />;
};

SSR

SSR = Server Side Rendering

ブラウザからのリクエストをトリガーに、サーバー上で JavaScript を実行し、API からデータを取得して、取得したデータをもとにサーバー側で HTML を生成する手法

getServerSideProps を pages 配下に記載することで利用可能

サンプルコード

pages / home / index.tsx

import { microCmsClient } from "~/lib/micro-cms-client";

import type { InferGetServerSidePropsType, NextPage } from "next";
import type { ComponentProps } from "react";

export const Home: NextPage<InferGetServerSidePropsType<typeof getServerSideProps>> = (props) => {
  const { contents } = props;
  return <HomeTemplate contents={contents} />
};

export default Home;

export const getServerSideProps = async () => {
  const data = await microCmsClient.get<ComponentProps<typeof HomeTemplate>>({ endpoint: "news" });
  return { props: { contents: data.contents } };
};

SG

SG = Static Generation

ビルド時に、サーバー上で JavaScript を実行し、API からデータを取得して、取得したデータをもとにサーバー側で HTML を生成する手法。ブラウザからのリクエストがあった場合には事前にビルドしたHTMLファイルを返す。

getStaticProps を pages 配下に記載することで利用可能

サンプルコード

pages / home / index.tsx

import { microCmsClient } from "~/lib/micro-cms-client";

import type { InferGetStaticPropsType, NextPage } from "next";
import type { ComponentProps } from "react";

export const Home: NextPage<InferGetStaticPropsType<typeof getStaticProps>> = (props) => {
  const { contents } = props;
  return <HomeTemplate contents={contents} />
};

export default Home;

export const getStaticProps = async () => {
  const data = await microCmsClient.get<ComponentProps<typeof HomeTemplate>>({ endpoint: "news" });
  return { props: { contents: data.contents } };
};

ISG

ISG = Incremental Static Generation

  • 初回リクエスト時にはSSRで完全なHTMLを生成しクライアントに返却(キャッシュもする)
  • 2回目以降のリクエスト時にはキャッシュを表示する

ISGを利用するためには?

  • dynamic SSG pages([id].tsx)を設定
  • getStaticPaths の返り値で fallback オプション を blocking や true に設定

サンプルコード

pages / home / [id].tsx

import { microCmsClient } from "~/lib/micro-cms-client";

import type { InferGetStaticPropsType, NextPage, GetStaticPaths } from "next";
import type { ComponentProps } from "react";

export const Home: NextPage<InferGetStaticPropsType<typeof getStaticProps>> = (props) => {
  const { contents } = props;
  return <HomeTemplate contents={contents} />
};

export default Home;

export const getStaticProps = async () => {
  const data = await microCmsClient.get<ComponentProps<typeof HomeTemplate>>({ endpoint: "news" });
  // MEMO(kimura): revalidate は 60秒 × 10 = 600秒(10分)に設定する
  return { props: { contents: data.contents }, revalidate: 10 * 60 };
};

export const getStaticPaths: GetStaticPaths = async () => {
  return { paths: [], fallback: 'blocking' }
}

ISR

ISR = Incremental Static ReGeneration

ブラウザからのリクエストをトリガーに、SG や ISG によって生成された静的ページを revalidate に指定した秒数経過ごとに最新の内容へ更新する手法

getStaticProps の返り値で revalidate に秒数を設定することで利用可能

サンプルコード

pages / home / index.tsx

import { microCmsClient } from "~/lib/micro-cms-client";

import type { InferGetStaticPropsType, NextPage } from "next";
import type { ComponentProps } from "react";

export const Home: NextPage<InferGetStaticPropsType<typeof getStaticProps>> = (props) => {
  const { contents } = props;
  return <HomeTemplate contents={contents} />
};

export default Home;

export const getStaticProps = async () => {
  const data = await microCmsClient.get<ComponentProps<typeof HomeTemplate>>({ endpoint: "news" });
  // MEMO(kimura): revalidate は 60秒 × 10 = 600秒(10分)に設定する
  return { props: { contents: data.contents }, revalidate: 10 * 60 };
};

On Demand ISR

On Demand ISR = On Demand Incremental Static ReGeneration

SG や ISG によって生成された静的ページを、要求に応じて最新の内容へ更新する手法

Next.js 12.1 で Beta版 がリリースされた。Next.js 12.2 で安定板がリリースされた。

On Demand ISR による再生成処理は pages / api に api を実装するのがお作法

詳しくは この文献 を参考にしていただけると

サンプルコード

TODO : いつか載せる

備考

上記サンプルコードで使用していたlib/micro-cms-client には以下のコードを記載しています。

import { createClient } from "microcms-js-sdk";

export const microCmsClient = createClient({
  serviceDomain: "microCMSのサービスドメイン",
  apiKey: process.env.MICRO_CMS_API_KEY || "",
});

参考文献

Discussion