SSR vs SSG: Choosing the Optimal Rendering Strategy: Claude Code 활용 가이드
ssr vs ssg: choosing the optimal rendering strategy: Claude Code 활용. 실용적인 팁과 코드 예시를 포함합니다.
SSR と SSG の基本
Web애플리케이션の렌더링方式は、성능と사용자体験に大きく影響します。Claude Code를 활용하면 프로젝트に最適な렌더링戦略を설계・구현할 수 있습니다。
| 特性 | SSR | SSG |
|---|---|---|
| 렌더링タイミング | 요청時 | 빌드時 |
| 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値を設定
判断フローチャート
렌더링方式を選ぶ際の判断基準です。코드 분할と組み合わせた최적화は코드 분할・지연 로딩を、엣지での配信에 대해서는엣지コンピューティング도 참고하세요.
- 콘텐츠は静的か → SSG
- 数分の遅延は許容できるか → ISR
- 실시간性が必要か → SSR
- 사용자固有の데이터か → SSR + 클라이언트フェッチ
상세 정보는Next.jsの렌더링가이드를 참고하세요.Claude Code의 활용법은공식 문서を확인합시다。
정리
SSR・SSG・ISRはどれかひとつに決める必要はなく、페이지の特性に応じて使い分けるのが最適です。Claude Code에프로젝트全体を分析させて、각페이지に最適な렌더링方式を提案してもらいましょう。
#Claude Code
#SSR
#SSG
#Next.js
#Astro
#performance