0
0

More than 1 year has passed since last update.

next.js ページのレンダリングについて CSR SSG ISR SSRの実装方法と動きの確認

Last updated at Posted at 2023-01-17

概要

nextjsの各レンダリング方法(CSR、SSG、ISR SSR)の実装方法、動きを確認します。
dynamic routingのような難しいことはしないで 初歩的な確認をします。

開発環境

フロントエンド:
IDE:VScode

├── @types/node@18.11.15
├── @types/react-dom@18.0.9
├── @types/react@18.0.26
├── axios@1.2.1
├── eslint-config-next@13.0.6
├── eslint@8.29.0
├── next-auth@4.18.7
├── next@13.0.6
├── react-bootstrap@2.7.0
├── react-dom@18.2.0
├── react@18.2.0
├── styled-components@5.3.6
├── styled-jsx@5.1.1
└── typescript@4.9.4

実装

CSR-Client Sever Rendering

Reactベースの手法です。nextjsの要素はないです。

ソースコード

csr.tsx
import { useEffect, useState } from "react";

function Csr(){
	const[products, setProducts] = useState([]);
	useEffect(() => {
		fetch('/dummy-backend.json')
		.then((response) => {
			return response.json();
		})
		.then((data) => {
			setProducts(data.products);
		});
}, []);

return(
	<div>
		<h1>CSR例</h1>
		<ul>
			{products.map((product : any) =>(
				<li key={product.id}>{product.title}</li>	
			))}		
		</ul>
	</div>
)
}

export default Csr;

ダミーデータを作成。クライアントサイドからアクセスできるようにpublicフォルダーに置きます

root/public/dummy-backend.json
{
	"products": [
	  { "id": "p1", "title": "Product 1", "description": "This is product 1" },
	  { "id": "p2", "title": "Product 2", "description": "This is product 2" },
	  { "id": "p3", "title": "Product 3", "description": "This is product 3" }
	]
  }

確認方法

以下コマンドを実行

npm run dev

ページを開きCtrl+Uを押してソースを表示する
image.png
データの取得はクライアントで行われるから、データの部分が入ってないですね。(赤線部分)

SSG-Static Side Rendering

ビルド時にデータを取得して、htmlに組み込む手法です。

ソースコード

ssg.tsx
import path from "path";
import fs from 'fs/promises';
import Link from "next/link";

function Ssg(props : any){
	const {products} = props;
	return(
		<div>
			<Link href="/ssg">SSG実装例</Link>

			<ul>
				{products.map((product : any) =>( 
				<li key ={product.id}>{product.title}</li>))}
			</ul>
		</div>
	);
}

export async function getStaticProps(){
	console.log('Regenerating...')
	const filePath = path.join(process.cwd(),'data','dummy-backend.json');
	const jsonData = await fs.readFile(filePath);
	const data =JSON.parse(jsonData as any);
	return{
		props:{
			products: data.products
		},
	};
}
export default Ssg;

データ

root/data/dummy-backend.json
{
	"products": [
	  { "id": "p1", "title": "Product 1", "description": "This is product 1" },
	  { "id": "p2", "title": "Product 2", "description": "This is product 2" },
	  { "id": "p3", "title": "Product 3", "description": "This is product 3" }
	]
  }

確認方法

buildコマンドを実行する

npm run build

ビルド結果 コンソールからSSGが作成されていることを確認。赤線部分注目
image.png

以下コマンドを実行してビルド結果を確認します。(一応npm run devでも確認はできます)

npm start

ページを開いてCtrl+Uを押してソースを表示する
image.png
赤線部分からhtmlにデータが入っています。サーバー側でデータを取得しhtmlに組み込んでいることを確認できます。

ISR-Incremental Static Regeneration

SSGの発展で一定間隔でデータの取得します。

ソースコード

SSGができれば簡単に実装できます。
revalidateを追加するだけです。

import path from "path";
import fs from 'fs/promises';
import Link from "next/link";

function Isr(props : any){
	const {products} = props;
	return(
		<div>
			<Link href="/ssg">ISR実装例</Link>
			
			<ul>
				{products.map((product : any) =>( 
				<li key ={product.id}>{product.title}</li>))}
			</ul>
		</div>
	);
}

export async function getStaticProps(){
	console.log('Regenerating...')
	const filePath = path.join(process.cwd(),'data','dummy-backend.json');
	const jsonData = await fs.readFile(filePath);
	const data =JSON.parse(jsonData as any);	
	if(!data){
		return{
	return{
		props:{
			products: data.products
		},
+		revalidate:10,
	};
}
export default ISR;

確認方法

ビルドしてログを確認

npm run build

ログの結果
image.png
赤線部分からISRになったことが確認できます。10秒おきにデータの再取得を行います。
以下コマンドを実行してサーバーを起動する

npm start

htmlソースコードの画像
image.png
赤線部からしてデータ入ってますね。

データ取得頻度の値を変えて比較

下gifアニメはISRのページに対して更新を連打している様子です。
データの取得が行われるとvscodeのコンソールに文字が出力されます。
1枚目は5秒 2枚目は1秒にしました。

間隔が5秒の時
ISR_take1.gif

間隔が1秒の時
ISR_take2.gif

SSGよりは使い勝手が良さそう

SSR Server Side Rendering

ソースコード

user-profile.tsx

function UserProfilePage(props : any) {
	console.log("Page")
	return <h1>{props.username}</h1>
  }
  
  export default UserProfilePage;
  
  export async function getServerSideProps(context: any) {
	console.log("SSR")
	const { params, req, res } = context;
	
	return {
	  props: {
		username: 'Max'
	  }
	};
  }

動きの確認

以下コマンドを押してビルド

npm run build

下の画像はビルド結果です。
image.png

htmlの結果 データ入ってますね。
image.png

下gifアニメは更新ボタンを連打している時の様子です。
押すごとにconsole.log('SSR')が実行されデータを取得していることを確認できます。

SSR _samole.gif

参考

Section5

0
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
0
0