はじめに

  • 「TypeScript と React/Next.js でつくる 実践 Web アプリケーション開発」の本を読んだ

next

next は各ファイルで使っているカタンすうやその関数の返す値によって pages のレンダリング手法が切り替わる。

SSG

ビルド時に API からデータを取得してページを描画して静的ファイルとして生成する。したがって、データの同期生はなくデータの更新がないような page でこのビルディング方式がパフォーマンスおよびレンダリング的に良い。

CSR

ビルド時にデータ取得を行わず、ページを描画して保存する。ブラウザで初期描画した後に非同期でデータを取得して、追加のデータを描画する

→ vue でいう所の SPA に該当する

SSR

ページのアクセスがある度サーバで getServerSideProps を呼び出し、その結果の props を元にページをサーバ側で描画してクライアントへ渡す。

ISR

ISR は SSG の応用のレンダリング手法のことをさす。事前にページを生成して配信しつつ、アクセスに応じてページを再度生成して新しいページを配信できる。要は一定間隔ごとに静的ファイルを作るようになる

ビルドまとめ

種別データ取得に使うメソッドデータ取得タイミング備考
SSGgetStaticPropsビルド時関数が指定されない場合 SSG のレンダリングが適用される
SSRgetServerSidePropsユーザのリクエスト時
ISRgetStaticPropsビルド時デプロイ後もバックグラウンドでビルドが実行される
CSR上記以外ユーザのリクエスト時CSR は SSG/SSR/ISR と同時に利用ができる

基本

SSG の実装

import { GetStaticProps, NextPage } from "next";
import Head from "next/head";

type SSGProps = {
  message: string
};

const SSG: NextPage<SSGProps> = props => {
  const { message } = props;
  return (
    <div>
      <Head>
        <title>Static Site Generation</title>
        <link rel="icon" href="/favicon.ico" />
      </Head>
      <main>
        <p>このサイトは静的サイトにより生成されたページ</p>
        <p>{message}</p>
      </main>
    </div>
  );
};

//getStaticPropsを記載して、本体はpropsを受け取ることができるようになる。
export const getStaticProps: GetStaticProps<SSGProps> = async context => {
  const timestamp = new Date().toLocaleString();
  const message = `${timestamp}にgetStaticPropsが実行された`;
  console.log(message);
  return {
    props: {
      message
    }
  };
};

export default SSG;

//npm run devをすると以下のようにアクセスごとにサーバアクセスがされている
// 2022/8/12 18:40:58にgetStaticPropsが実行された
// 2022/8/12 18:41:07にgetStaticPropsが実行された
// 2022/8/12 18:41:09にgetStaticPropsが実行された

//npm run buildをした後にnpm run startをすると
//console.logの表示はされなくなり、ビルドされた時の値が画面に描画される。

getStaticPropsを用いることで props を使うことができるようになる。 フォールバック時の挙動が違う。getStaticPathsの return の fallback を true にした場合、一番最初に訪れたユーザはフォールバックのページが表示される。サーバーサイドではリクエストのパスに対してgetStaticPropsを実行するようになる。getStaticPropsが返した props はページを表示しているクライアントに送られ、再描画される。この結果はサーバサイドでは保存するようになる。また、getStaticPropsは必ずサーバサイドで実行される。

SSR の実装

SSR ではアクセスする度にページを描画してその結果をクライアントで表示する。

import { GetServerSideProps, NextPage } from "next";
import Head from "next/head";

type SSRProps = {
  message: string
};

const SSR: NextPage<SSRProps> = props => {
  const { message } = props;
  return (
    <div>
      <Head>
        <title>Static Site Generation</title>
        <link rel="icon" href="/favicon.ico" />
      </Head>
      <main>
        <p>このサイトはサーバサイドにより生成されたページ</p>
        <p>{message}</p>
      </main>
    </div>
  );
};

//GetServerSidePropsで定義する。
export const getServerSideProps: GetServerSideProps<SSRProps> = async context => {
  const timestamp = new Date().toLocaleString();
  const message = `${timestamp}にgetServerSidePropsが実行された`;
  console.log(message);
  return {
    props: {
      message
    }
  };
};

export default SSR;

ISR による実装

SSG の応用のレンダリング手法である。ページに寿命を設定することができ、寿命をすぎたページについては最新の情報での再生成を試みて静的ページを配信しつつ情報を更新できる。

import { GetStaticProps, NextPage, GetStaticPaths } from "next";
import Head from "next/head";

type ISRProps = {
  message: string
};

const ISR: NextPage<ISRProps> = props => {
  const { message } = props;
  return (
    <div>
      <Head>
        <title>Static Site Generation</title>
        <link rel="icon" href="/favicon.ico" />
      </Head>
      <main>
        <p>このサイトはISRにより生成されたページ</p>
        <p>{message}</p>
      </main>
    </div>
  );
};

export const getStaticProps: GetStaticProps<ISRProps> = async context => {
  const timestamp = new Date().toLocaleString();
  const message = `${timestamp}にgetStaticPropsが実行された`;
  console.log(message);
  return {
    props: {
      message
    },
    //revalidateを指定することで有効期限を設定できる
    revalidate: 5
  };
};

export default ISR;
  • ユーザが初めてアクセスした場合は SSG と同様
  • フォールバック表示してサーバ側で実行した getStaticProps を元にクライアントで再描画する。
  • revalidate で有効期限を設定し、それ以降にアクセスがあった場合再描画する。その期限以内であればキャッシュしているページデータを返す

遷移

import Link from 'next/link'

//Linkタグを利用してaタグを囲む
<Link href="ssr">
  <a>go to ssr</a>
</Link>

//オブジェクトで指定する
///ssg?keyword=hello になる
<Link href={{pathname:'/ssg',query:{keyword:"hello"}}}>
  <a>go to ssr</a>
</Link>

//buttonでも可能
<Link href="ssr">
  <buttuon>go to ssr</buttuon>
</Link>

画像

画像の最適化が行われて表示することができる。ただし、Image タグを使う場合はwidth,heightを指定する必要がある。静的コンテンツを参照 path に置く場合は必要ない。

import { NextPage } from "next";
import Image from "next/image";
import SampleImage from "../public/sample.jpg";

const ImageSample: NextPage<void> = props => {
  return (
    <div>
      <h1>画像</h1>
      <Image src={SampleImage} />
    </div>
  );
};

環境変数

.envファイルを処理できる。プロジェクトルートの場所に位置させることで読み込むことができるようになっている。

  • .env.development
  • .env.stage
  • .env.production
プロフィール
Kobasan
現在都内のWeb会社で働いている人です.主にこれまで,Web関連及び機械学習周りのことをやってきました.このブログではそれらの内容を含む,ちょっとした私の備忘録を記載するものです.