Comparison

SSR vs SSG:Claude Codeで最適なレンダリング戦略を選ぶ

SSR(サーバーサイドレンダリング)とSSG(静的サイト生成)の違いをClaude Codeでの実装例を交えて比較。Next.js/Astroでの実践的な使い分けガイド。

SSR と SSG の基本

Webアプリケーションのレンダリング方式は、パフォーマンスとユーザー体験に大きく影響します。Claude Codeを使えば、プロジェクトに最適なレンダリング戦略を設計・実装できます。

特性SSRSSG
レンダリングタイミングリクエスト時ビルド時
TTFBやや遅い非常に速い
データの鮮度常に最新ビルド時点
サーバー負荷高い低い(CDN配信)
向いているコンテンツ動的コンテンツ静的コンテンツ

SSR の実装(Next.js)

// app/products/[id]/page.tsx
import { notFound } from "next/navigation";

interface ProductPageProps {
  params: { id: string };
}

// SSR: リクエストごとに実行
export default async function ProductPage({
  params,
}: ProductPageProps) {
  const product = await fetch(
    `https://api.example.com/products/${params.id}`,
    { cache: "no-store" } // SSR: キャッシュしない
  ).then((res) => res.json());

  if (!product) {
    notFound();
  }

  return (
    <div>
      <h1>{product.name}</h1>
      <p>価格: ¥{product.price.toLocaleString()}</p>
      <p>在庫: {product.stock}</p>
      <p>最終更新: {new Date().toLocaleString("ja-JP")}</p>
    </div>
  );
}

SSG の実装(Next.js)

// app/blog/[slug]/page.tsx
import { getAllPosts, getPostBySlug } from "@/lib/posts";

// SSG: ビルド時に全ページを生成
export async function generateStaticParams() {
  const posts = await getAllPosts();
  return posts.map((post) => ({
    slug: post.slug,
  }));
}

export default async function BlogPost({
  params,
}: {
  params: { slug: string };
}) {
  const post = await getPostBySlug(params.slug);

  return (
    <article>
      <h1>{post.title}</h1>
      <time>{post.publishedAt}</time>
      <div dangerouslySetInnerHTML={{ __html: post.content }} />
    </article>
  );
}

ISR(Incremental Static Regeneration)

SSGとSSRの良いところ取りができるISRも選択肢です。

// app/news/page.tsx
export const revalidate = 60; // 60秒ごとに再生成

export default async function NewsPage() {
  const news = await fetch("https://api.example.com/news").then(
    (res) => res.json()
  );

  return (
    <div>
      <h1>最新ニュース</h1>
      {news.map((item: any) => (
        <article key={item.id}>
          <h2>{item.title}</h2>
          <p>{item.summary}</p>
        </article>
      ))}
    </div>
  );
}

Astro での SSG

---
// src/pages/blog/[slug].astro
import { getCollection } from "astro:content";
import BlogLayout from "@/layouts/BlogLayout.astro";

export async function getStaticPaths() {
  const posts = await getCollection("blog");
  return posts.map((post) => ({
    params: { slug: post.slug },
    props: { post },
  }));
}

const { post } = Astro.props;
const { Content } = await post.render();
---

<BlogLayout title={post.data.title}>
  <article>
    <h1>{post.data.title}</h1>
    <Content />
  </article>
</BlogLayout>

ハイブリッド戦略

1つのプロジェクト内でSSR・SSG・ISRを使い分ける実践的なパターンです。

// ページごとの最適な戦略
const renderingStrategy = {
  // SSG: 更新頻度が低い
  "/about": "SSG",
  "/blog/*": "SSG",
  "/docs/*": "SSG",

  // ISR: 定期的に更新
  "/products/*": "ISR (60s)",
  "/categories/*": "ISR (300s)",

  // SSR: リアルタイム性が必要
  "/dashboard": "SSR",
  "/search": "SSR",
  "/cart": "SSR",
};

パフォーマンス比較

Claude Codeにパフォーマンスの計測と最適化を依頼できます。

各ページのレンダリング方式を分析して最適化して。
- LighthouseスコアをSSR/SSG/ISRで比較
- TTFBとLCPの改善提案
- 静的化できるページを特定して SSG に変更
- 動的ページにはISRの適切なrevalidate値を設定

判断フローチャート

レンダリング方式を選ぶ際の判断基準です。コード分割と組み合わせた最適化はコード分割・遅延読み込みを、エッジでの配信についてはエッジコンピューティングも参照してください。

  1. コンテンツは静的か → SSG
  2. 数分の遅延は許容できるか → ISR
  3. リアルタイム性が必要か → SSR
  4. ユーザー固有のデータか → SSR + クライアントフェッチ

詳細はNext.jsのレンダリングガイドを参照してください。Claude Codeの活用法は公式ドキュメントを確認しましょう。

まとめ

SSR・SSG・ISRはどれかひとつに決める必要はなく、ページの特性に応じて使い分けるのが最適です。Claude Codeにプロジェクト全体を分析させて、各ページに最適なレンダリング方式を提案してもらいましょう。

#Claude Code #SSR #SSG #Next.js #Astro #パフォーマンス