【React】Next.jsの基本のレンダリング(CSR/SSR/SSG/ISR)

この記事は個人学習の備忘録です。

Udemyの講座[【2023年最新】React(v18)完全入門ガイド｜Hooks、Next.js、Redux、TypeScript(CodeMafia)](https://www.udemy.com/course/react-complete-guide/)

上記を参考・引用しながらNext.jsの基本のレンダリングについて個人的に学んだことのアウトプット記事です。

## 基本のレンダリング

Next.jsでは４種類のレンダリングが行われます。

1\. CSR-クライアントサイドレンダリング
2\. SSR-サーバーサイドレンダリング
3\. SSG-静的サイト生成
4\. ISR-インクリメンタル静的再生成

中でも、Next.jsで用いられる基本的なレンダリングは下記の２つです。

- **SSR-サーバーサイドレンダリング**
- **SSG-静的サイト生成**

なぜこれらのレンダリングが必要になったかの背景と、その特徴について紹介します。

## 1.CSR-クライアントサイドレンダリング

CSRでは、データフェッチやルーティングの全てがクライアント上で行われます。
通常のReact開発は、CSRに分類されます。基本的にはNext.jsではあまり使われない概念になっています。
![csr.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3288047/0d0dbd1c-3d46-b1fc-ebbc-11da784e8299.png)
①最初にクライアントでURLが指定されると、HTTPリクエストがNode.js(サーバー)に対して送信される。
②③そこに置いてあるHTMLファイルなどが返却され、クライアント側でReactが動作。
例えばuseEffectにfetchの処理が書いてある場合は、APIサーバーに対してJSONなどを取得しにいく動作が走る。
④JSONデータを受け取って、クライアント側の描写が完了する。

:::note
**メリット**
- 静的なファイルの配置のみで動く
- Node.jsの実行は必要ないため、サーバの負荷が軽い
:::

:::note alert
**デメリット**
- 初期描写までに時間がかかる
- クローラーによっては**SEO的な問題あり**
:::

HTMLを取得した段階では、まだHTMLの構築自体は完了していない状態であるため、SEOに問題がある場合がある。GoogleのクローラーはJavascriptも実行できるため、Javascriptを取得した状態も取得できるが、クローラーの種類によっては正常にページの内容が読み込めない場合がある。

このような問題を解決するために生み出されたのが**SSR(サーバーサイドレンダリング)** である。

※Next.jsを使用して、クライアントサイドでのみ処理を行いたい場合はuseEffectで囲む必要があります。

## 2.SSR-サーバーサイドレンダリング

- Node.js(サーバー)にリクエストが来たタイミングで動的にHTMLを作成。
- 外部APIへのデータの取得やコンポーネントのpropsの値を決定する処理を行い、HTMLを作成したクライアント側に返却する。

こちらの処理は、Node.js上で動くと考えます。この時、例えば外部APIにデータを取得するような処理が含まれている場合には、Node.js上でデータの取得を行うことにもなります。
そのような処理をNode.jsで行ってHTMLを作成したものをクライアント側で返却することになります。

ポイントは、**Node.js上でHTMLを組み上げるということ**です。
![ssr.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3288047/0d7132da-168b-1437-86f9-ca8fec1f6ad1.png)
①まず、クライアント側でURLが指定されるとNode.jsに対してHTTPリクエストが送信される。
②この時データフェッチが必要な場合にはこのNode.jsからAPIサーバに対してデータの取得が行われることになる。
③この上で、取得したデータを元にHTMLを構築して、それをクライアント側に返す。
そのため、フロント側に帰ってきたHTMLはすでに構築された状態にあるということです。

:::note
**メリット**
- 生成済みのHTMLを取得するのでSEOに強い
:::

:::note alert
**デメリット**
- 生成処理を全てサーバー側で行うため負担が大きい
- HTMLをクライアントに渡すまで時間がかかる
:::

## 3.SSG(Static Site Generator)-静的サイト生成

- **ビルド時**にデータフェッチやpropsの値の決定を行い、HTMLを構築する
- クライアントからリクエストされたら、サーバー側で構築することなく、生成済みのHTMLを渡す。

あらかじめ、**ビルドするとき**にデータフェッチやpropsの値の決定を行ってから、HTMLを生成します。
先ほどのSSRでは、**リクエストが来たタイミング**でHTMLを作成していました点が違いになります。
![ssg.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3288047/9ffd2318-7fa5-df07-f871-0f2d49b5a322.png)
①まずビルドの時にHTMLを作成。この時、APIデータ上などのデータが必要な場合にはここへの問いあわせも含めて全て保管した状態でHTMLを作成して、それをNode.js上に置いておく。
②③クライアントからHTTPリクエストが飛んできた場合には、すでに生成済みのHTMLをまたクライアントに返すことになる。

:::note
**メリット**
- 構築済みページのため表示速度が早い。
- SEOも問題なし
:::

:::note alert
**デメリット**
- 更新頻度が高い動的コンテンツとの相性が悪い
:::

ブラウザのURLを指定してから画面が表示されるまでは、基本的にサーバー側の処理の後、ブラウザ上でJavaScriptがどれだけ実行されないかで表示の速さが決まってきます。
SSGではもうすでに生成済みのHTMLが準備された状態で、それがブラウザ側に返却されるだけなので、サーバー側のレスポンスも早く、ブラウザ側でのJavaScriptの処理も最小限で済むため、その分ページの表示速度が速くなってきます。

## 4.ISR(Incremental Static Regeneration)-インクリメンタル静的再生成

- ビルド時にHTMLを構築
- 一定時間後にアクセスがあった場合、生成済みのHTMLを返しつつ、サーバー側でHTMLを更新
- 次のアクセス時に最新のHTMLを渡す

こちらもSGと同様にビルド時にHTMLを構築します。一定時間後にアクセスがあった場合、生成済みのHTMLをとりあえず返します。同時にサーバー側でHTMLを最新に更新します。
これによって、次にアクセスがあった場合に最新のHTMLを返すことができます。
![isr.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3288047/b667342a-8de3-c6b3-346c-1b9c7277aaf5.png)
①まず初回のビルドで生成済みHTMLをNode.jsに配置。
②③次にクライアントからHTTPリクエストを受け取り、とりあえずHTMLを返却。
④一定時間後にアクセスがあった場合には、バックグラウンドでHTMLを再生成。
⑤⑥次回リクエストがあった際には最新のHTMLを返却。

:::note
**メリット**
- SSGを利用しながら、動的なコンテンツも更新できる。
:::

:::note alert
**デメリット**
- サーバーの設定が少し手間
:::

## Next.jsの基本構成

基本的なページは**SSG-静的サイト生成**、更新頻度が多いページや、動的に作成する必要があるページは**SSR-サーバーサイドレンダリング**を適応させるのが適しています。

## 参考


https://www.udemy.com/course/react-complete-guide/