👀
Next.jsの「コンポーネントの種類」と「レンダリング方式」は別の話
最初に整理:2つの異なる概念
Next.jsを学習していると、こんな用語がたくさん出てきます:
- Server Component / Client Component
- SSR / CSR / SSG
これらは全部「サーバー」や「クライアント」という言葉が入っているので、同じような概念に見えますよね。でも実は、まったく別の話なんです。
コンポーネントの種類(RSC/RCC) = 「どこでコードが実行されるか」
レンダリング方式(SSR/CSR/SSG) = 「いつHTMLが作られるか」
この2つは独立した概念で、組み合わせて使うものです。
コンポーネントの種類を理解する
Server Component(サーバーコンポーネント)
// app/products/page.tsx
export default async function ProductsPage() {
// このコードはサーバーでのみ実行される
const products = await fetch('https://api.example.com/products');
return (
<div>
<h1>商品一覧</h1>
{products.map(product => (
<div key={product.id}>{product.name}</div>
))}
</div>
);
}
特徴: サーバーでのみ実行、データベース直接アクセス可、JavaScriptバンドルに含まれない
Client Component(クライアントコンポーネント)
// components/LikeButton.tsx
"use client"
import { useState } from 'react';
export default function LikeButton() {
// このコードはブラウザでも実行される
const [liked, setLiked] = useState(false);
return (
<button onClick={() => setLiked(!liked)}>
{liked ? '❤️ いいね済み' : '🤍 いいね'}
</button>
);
}
特徴: ブラウザで実行、React Hooks使用可、JavaScriptバンドルに含まれる
レンダリング方式を理解する
- SSR(Server-Side Rendering): リクエストのたびにサーバーでHTMLを作る
- SSG(Static Site Generation): ビルド時にあらかじめHTMLを作っておく
- CSR(Client-Side Rendering): ブラウザでHTMLを作る
よくある混乱:「Server Component = SSR」ではない
多くの人がこう思いがちです:
❌ 間違った理解
Server Component → サーバーでHTML作成 → SSR
Client Component → ブラウザでHTML作成 → CSR
でも実際は:
✅ 理論的には正しい組み合わせ
Server Component + SSR → サーバーコンポーネントをリクエスト時にHTML化
Server Component + SSG → サーバーコンポーネントをビルド時にHTML化
Client Component + SSR → クライアントコンポーネントをリクエスト時にHTML化
Client Component + CSR → クライアントコンポーネントをブラウザでHTML化
Next.jsの実際のデフォルト動作
ただし、Next.js App Routerでは、可能な限り事前にHTML化することを優先します:
📋 Next.jsのデフォルト動作
Server Component → 自動的に静的最適化(SSG的な動作)
Client Component → デフォルトでSSR(初回はサーバーでHTML化)
つまり、何も指定しなければ、ほとんどのコンテンツが事前にHTML化されます。
実際の組み合わせ例
パターン1:Server Component(デフォルト = 静的最適化)
// app/blog/page.tsx
export default async function BlogPage() {
// デフォルトで静的最適化される
const posts = await getPosts();
return (
<div>
<h1>ブログ</h1>
{posts.map(post => (
<article key={post.id}>
<h2>{post.title}</h2>
<p>{post.excerpt}</p>
</article>
))}
</div>
);
}
結果: 高速表示、SEOに優しい、サーバー負荷軽減
パターン2:Client Component(デフォルト = SSR + ハイドレーション)
// components/SearchForm.tsx
"use client"
import { useState } from 'react';
export default function SearchForm() {
const [query, setQuery] = useState('');
return (
<form>
<input
value={query}
onChange={(e) => setQuery(e.target.value)}
placeholder="検索..."
/>
<button type="submit">検索</button>
</form>
);
}
結果: 最初からフォームが表示され、その後インタラクティブになる
パターン3:Client Component + 明示的CSR
import dynamic from 'next/dynamic';
const ClientOnlyChart = dynamic(
() => import('./Chart'),
{ ssr: false } // 明示的にSSRを無効化
);
export default function DashboardPage() {
return (
<div>
<h1>ダッシュボード</h1>
<ClientOnlyChart />
</div>
);
}
結果: タイトルは即座に表示、チャートは少し遅れて表示
実践的な判断基準
Server Componentを選ぶとき
- データベースアクセスが必要
- SEOが重要
- ユーザーインタラクションが不要
Client Componentを選ぶとき
- useState、useEffectが必要
- ブラウザAPIを使用
- ユーザーインタラクションが必要
CSRを明示的に選ぶとき
- SEOが不要(管理画面など)
- 明示的に
ssr: falseを指定する必要がある
組み合わせの実例
// app/shop/page.tsx
export default async function ShopPage() {
// Server Component + 静的最適化(デフォルト)
const products = await getProducts();
return (
<div>
<h1>オンラインショップ</h1>
<ProductList products={products} /> {/* Server Component */}
<SearchForm /> {/* Client Component(SSR) */}
<ShoppingCart /> {/* Client Component(CSR) */}
</div>
);
}
この例では:
- 商品リスト:SEOのためServer Component(静的最適化)
- 検索フォーム:インタラクションが必要なのでClient Component(デフォルトでSSR)
- ショッピングカート:ユーザー専用データなので明示的にCSR化
まとめ
Next.jsの「コンポーネントの種類」と「レンダリング方式」は別々の概念です:
コンポーネントの種類(どこで実行?)
- Server Component:サーバーでのみ実行
- Client Component:ブラウザで実行(サーバーでも実行される場合あり)
レンダリング方式(いつHTML生成?)
- SSR:リクエスト時
- SSG:ビルド時
- CSR:ブラウザで
Next.jsのデフォルト動作:
- Server Component → 静的最適化(SSG的)
- Client Component → SSR + ハイドレーション
- CSRは明示的指定が必要(
ssr: false)
「どこで実行するか」と「いつHTML化するか」を分けて考え、Next.jsのデフォルト動作(可能な限り事前HTML化)を理解すると使いやすくなります。実際にコードを書きながら、それぞれの特徴を体感してみてください!
Discussion