Next.js CSRとISRの使い分けを初心者向けに解説!具体例でわかるNext.jsのレンダリング方法
生徒
「先生、Next.jsってCSRとISRって何が違うんですか?」
先生
「CSRはClient Side Renderingで、ブラウザ側でページを作る方法です。ISRはIncremental Static Regenerationで、一度作ったページを一定時間ごとに自動で更新する方法です。」
生徒
「具体的にはどんなときにCSRを使って、どんなときにISRを使えばいいですか?」
先生
「それでは、実際の例を見ながらわかりやすく説明しましょう!」
1. CSR(Client Side Rendering)とは?
CSRはブラウザがページを表示するときに、必要なデータをサーバーから取得してからページを作る方法です。つまり、初めにHTMLがほとんど空の状態で送られ、JavaScriptが動いてデータを表示します。
たとえば、ユーザーがログインして自分のプロフィールを見るページは、CSRが向いています。なぜなら、表示内容がユーザーごとに変わるため、サーバーで静的に作ることができないからです。
import { useEffect, useState } from "react";
function UserProfile() {
const [userName, setUserName] = useState("");
useEffect(() => {
fetch("/api/user")
.then(res => res.json())
.then(data => setUserName(data.name));
}, []);
return <h1>こんにちは、{userName}さん!</h1>;
}
export default UserProfile;
2. ISR(Incremental Static Regeneration)とは?
ISRは静的に作ったページを、一度作成したあとも一定の時間ごとに自動で更新する方法です。静的ページの高速表示と、新しいデータ反映の両方を実現できます。
例えば、ブログ記事一覧ページやニュースサイトで新しい記事が追加されるときに、ISRを使うと便利です。ユーザーがアクセスしたときに古いHTMLがあっても、指定した時間で新しいHTMLに更新されます。
export async function getStaticProps() {
const res = await fetch("https://api.example.com/posts");
const posts = await res.json();
return {
props: { posts },
revalidate: 60, // 60秒ごとにページを再生成
};
}
function Blog({ posts }) {
return (
<ul>
{posts.map(post => (
<li key={post.id}>{post.title}</li>
))}
</ul>
);
}
export default Blog;
3. CSRとISRの大きな違いを整理しよう
簡単に違いをまとめると:
- CSR:ブラウザでデータを取得してページを作る。ユーザーごとに変わるデータに向く。
- ISR:一度静的に作ったページを、定期的に自動で更新。高速表示と最新データの両立が可能。
CSRは動的に変わるデータ向き、ISRは主に内容が頻繁に変わるが全体的には同じ構造のページに向いています。
4. 実際の使い分け例:SNSプロフィールとニュースサイト
たとえば、SNSのプロフィールページはCSRが適しています。ログインしているユーザーごとに内容が変わるからです。
function ProfilePage() {
const [profile, setProfile] = useState(null);
useEffect(() => {
fetch("/api/profile")
.then(res => res.json())
.then(data => setProfile(data));
}, []);
if (!profile) return <p>読み込み中...</p>;
return <h1>{profile.name}のプロフィール</h1>;
}
export default ProfilePage;
一方、ニュースサイトのトップページはISRが便利です。全ユーザーに同じ構造のページを高速に表示しつつ、新しい記事は定期的に反映できます。
5. CSRを選ぶときのポイント
CSRは動的データやユーザーごとに変わる情報を扱うページに最適です。ただし、初回表示が少し遅くなることがあります。例えば、ログイン後のマイページやカート情報の表示などです。
function Cart() {
const [items, setItems] = useState([]);
useEffect(() => {
fetch("/api/cart")
.then(res => res.json())
.then(data => setItems(data));
}, []);
return (
<div>
<h2>カート内商品</h2>
<ul>
{items.map(item => (
<li key={item.id}>{item.name} - {item.price}円</li>
))}
</ul>
</div>
);
}
export default Cart;
6. ISRを選ぶときのポイント
ISRは大量のユーザーに同じページを高速表示したいときや、定期的に情報を更新したいときに使います。アクセスが多いブログやニュース、商品一覧ページに向いています。
export async function getStaticProps() {
const res = await fetch("https://api.example.com/products");
const products = await res.json();
return {
props: { products },
revalidate: 120, // 2分ごとにページを更新
};
}
function ProductList({ products }) {
return (
<ul>
{products.map(p => (
<li key={p.id}>{p.name} - {p.price}円</li>
))}
</ul>
);
}
export default ProductList;
まとめ
今回の記事では、Next.jsにおけるCSR(Client Side Rendering)とISR(Incremental Static Regeneration)の基本的な使い分けについて詳しく解説しました。CSRはブラウザ側でデータを取得してページを動的に生成する方式であり、ユーザーごとに異なる情報を表示する場合や、ログイン後のマイページ、カート情報、SNSプロフィールなどの動的コンテンツに最適です。一方、ISRは静的に生成したページを定期的に再生成する仕組みで、高速なページ表示と最新データ反映の両立が可能です。特にニュースサイト、ブログ記事一覧、商品一覧ページなど、内容が頻繁に更新されるが基本的なページ構造は同じ場合に適しています。
具体的なコード例を通して、CSRではuseEffectやuseStateを活用してAPIからデータを取得し、動的に表示する方法を示しました。また、ISRではgetStaticPropsとrevalidateプロパティを用いて、静的ページを一定時間ごとに自動更新する方法を解説しました。これにより、ユーザーがアクセスしたときに古い情報が表示されることを防ぎつつ、サーバー負荷を抑えて高速な表示を実現できます。
CSRとISRの使い分けのポイントとしては、まず「データがユーザーごとに変わるかどうか」を確認することが重要です。動的で個別データが必要な場合はCSRを選び、全体構造は同じだが更新頻度がある程度あるデータはISRを選ぶと効率的です。また、初回表示速度やSEOの観点からも、ISRを利用することで静的ページの利点を活かしつつ最新情報を提供できるため、ニュースやECサイトでの活用価値が高いです。
さらに、Reactコンポーネントでの実装例として、ユーザー名を表示するCSRのサンプルや、ブログ記事や商品一覧を表示するISRのサンプルを示しました。CSRでは初回レンダリング時に読み込み中の表示を入れることでUXを向上させ、ISRではrevalidate秒数を調整することで、ページの更新頻度と表示速度を最適化できます。
import { useEffect, useState } from "react";
function ExampleCSR() {
const [data, setData] = useState(null);
useEffect(() => {
fetch("/api/data")
.then(res => res.json())
.then(json => setData(json));
}, []);
if (!data) return <p>読み込み中...</p>;
return <h2>{data.title}</h2>;
}
export default ExampleCSR;
export async function getStaticProps() {
const res = await fetch("https://api.example.com/items");
const items = await res.json();
return {
props: { items },
revalidate: 180, // 3分ごとにページを自動更新
};
}
function ExampleISR({ items }) {
return (
<ul>
{items.map(item => (
<li key={item.id}>{item.name}</li>
))}
</ul>
);
}
export default ExampleISR;
生徒
「先生、CSRとISRの違いがよくわかりました。CSRはユーザーごとに内容が変わるページに使うんですね。」
先生
「その通りです。CSRはブラウザ側でデータを取得して動的にレンダリングするので、個別情報の表示に向いています。」
生徒
「じゃあ、ニュースサイトやブログ記事の一覧ページはISRの方が向いているんですね?」
先生
「そうです。ISRなら一度静的に生成したページを定期的に更新できるので、ページの表示速度を維持しつつ最新情報を反映できます。」
生徒
「どちらを使うか迷ったら、まずユーザーごとの動的データかどうかで判断すればいいですね。」
先生
「その通りです。そして、初回表示速度やアクセス数に応じてrevalidateの時間を調整することで、ISRの利点を最大限活かすことができます。」
生徒
「なるほど、これでCSRとISRの使い分けが実際の開発でもすぐに応用できそうです!」