Files
2nd/10_Wiki/Topics/Frontend/웹 렌더링 전략 (CSR, SSR, SSG, ISR).md
T
2026-05-10 22:08:15 +09:00

6.8 KiB

id, title, category, status, canonical_id, aliases, duplicate_of, source_trust_level, confidence_score, verification_status, tags, raw_sources, last_reinforced, github_commit, tech_stack
id title category status canonical_id aliases duplicate_of source_trust_level confidence_score verification_status tags raw_sources last_reinforced github_commit tech_stack
wiki-2026-0508-웹-렌더링-전략-csr-ssr-ssg-isr 웹 렌더링 전략 (CSR, SSR, SSG, ISR) 10_Wiki/Topics verified self
Web Rendering Strategies
CSR vs SSR
Static Generation
Incremental Static Regeneration
RSC
none A 0.93 applied
frontend
rendering
ssr
ssg
csr
isr
rsc
nextjs
2026-05-10 pending
language framework
TypeScript Next.js 15, Remix, Astro 5, Qwik

웹 렌더링 전략 (CSR, SSR, SSG, ISR)

매 한 줄

"매 페이지 마다 매 적절한 rendering 시점 의 선택 — 매 CSR / SSR / SSG / ISR / RSC 의 spectrum". 매 2010s SPA 의 CSR-only era 의 종료, 매 2020s Next.js 13+ App Router 의 RSC (React Server Components) 의 매 default 화. 매 2026 매 mix-and-match — 매 한 page 안 의 static shell + streaming SSR + island hydration 의 공존.

매 핵심

매 Strategy Spectrum

전략 매 HTML 생성 시점 매 JS hydration 매 use case
CSR 매 client runtime 매 모든 것 dashboard, internal tool
SSR 매 request time (server) 매 full dynamic personalized
SSG 매 build time 매 full / partial blog, docs, marketing
ISR 매 build + on-demand revalidate 매 full / partial e-commerce catalog
RSC 매 server (no client JS for component) 매 client component 만 매 modern Next.js default
Streaming SSR 매 server, 매 chunk-by-chunk 매 progressive 매 large interactive page

매 Trade-off

  • CSR — 매 TTI (Time-to-Interactive) 의 빠름 (after JS load), 매 FCP 의 느림, 매 SEO 의 약함.
  • SSR — 매 FCP 의 빠름, 매 TTFB 의 느림 (server compute), 매 cache 의 어려움.
  • SSG — 매 가장 빠른 TTFB, 매 CDN 의 무한 scale, 매 stale 의 risk.
  • ISR — SSG 의 stale 의 해결, 매 first request 의 stale 의 가능.
  • RSC — 매 client bundle 의 축소, 매 framework lock-in.

매 RSC (React Server Components) 의 의미

  • 매 component tree 의 server / client 의 split.
  • Server component — 매 DB 의 직접 fetch, 매 secret 의 access, 매 client JS 의 X.
  • Client component — 'use client' 의 마킹, 매 useState/useEffect 의 사용.
  • 매 server payload 의 binary serialization (RSC wire format).

💻 패턴

Pattern 1: Next.js 15 Server Component (default)

// app/posts/page.tsx — 매 server 의 실행, 매 client JS 의 X
import { db } from '@/lib/db';

export default async function PostsPage() {
  const posts = await db.posts.findMany({ orderBy: { createdAt: 'desc' } });
  return (
    <ul>
      {posts.map(p => <li key={p.id}>{p.title}</li>)}
    </ul>
  );
}

Pattern 2: Client Component (interactivity)

'use client';
import { useState } from 'react';

export function LikeButton({ postId }: { postId: string }) {
  const [liked, setLiked] = useState(false);
  return (
    <button onClick={() => setLiked(!liked)}>
      {liked ? '♥' : '♡'}
    </button>
  );
}

Pattern 3: Static Generation (SSG)

// app/blog/[slug]/page.tsx
export async function generateStaticParams() {
  const posts = await getAllPosts();
  return posts.map(p => ({ slug: p.slug }));
}

export default async function PostPage({ params }: { params: { slug: string } }) {
  const post = await getPost(params.slug);
  return <Article post={post} />;
}

Pattern 4: ISR (Incremental Static Regeneration)

// app/products/[id]/page.tsx
export const revalidate = 3600; // 매 1시간 마다 background revalidate

export default async function ProductPage({ params }) {
  const product = await fetchProduct(params.id);
  return <ProductDetail product={product} />;
}

// 매 on-demand revalidation
import { revalidatePath } from 'next/cache';
export async function POST(req: Request) {
  const { path } = await req.json();
  revalidatePath(path);
  return Response.json({ revalidated: true });
}

Pattern 5: Streaming SSR with Suspense

import { Suspense } from 'react';

export default function Dashboard() {
  return (
    <>
      <Header /> {/* 매 즉시 stream */}
      <Suspense fallback={<Skeleton />}>
        <SlowAnalytics /> {/* 매 chunk 의 도착 시 stream */}
      </Suspense>
      <Suspense fallback={<Skeleton />}>
        <SlowFeed />
      </Suspense>
    </>
  );
}

Pattern 6: Astro 5 Islands

---
// 매 build-time 의 server, 매 client JS 의 zero by default
import Counter from './Counter.tsx';
const posts = await Astro.glob('./posts/*.md');
---
<html>
  <body>
    <h1>Blog</h1>
    {posts.map(p => <article>{p.frontmatter.title}</article>)}
    <Counter client:visible /> {/* 매 viewport 의 진입 시 hydrate */}
  </body>
</html>

Pattern 7: Edge Runtime (SSR at edge)

// app/api/geo/route.ts
export const runtime = 'edge';

export async function GET(req: Request) {
  const country = req.headers.get('x-vercel-ip-country') ?? 'US';
  return Response.json({ country });
}

매 결정 기준

상황 전략
Marketing / docs site SSG (Astro, Next.js)
E-commerce catalog ISR (revalidate=3600)
Personalized feed SSR + RSC
Real-time dashboard CSR + SWR/React Query
Hybrid (static shell + dynamic island) RSC + Client Components
Geo-aware routing Edge SSR
SEO + interactivity Streaming SSR with Suspense

기본값: 매 Next.js 15 App Router — RSC default, Suspense streaming, ISR revalidate 의 사용.

🔗 Graph

🤖 LLM 활용

언제: 매 page 의 적절한 rendering strategy 의 권고, RSC server/client boundary 의 review, revalidate 의 적절한 시간 의 제안. 언제 X: 매 specific framework migration 의 detailed plan — 매 codebase 의 scan 의 X.

안티패턴

  • 모든 페이지 의 SSR: 매 cold-start latency, 매 cost 의 polynomial 증가.
  • CSR 의 SEO-critical page: 매 GoogleBot 의 partial 만 render → 매 ranking 손실.
  • Server Component 의 useState: 매 build error.
  • Client Component 의 DB query: 매 client 의 secret leak.
  • ISR 의 revalidate=1: 매 cache 의 의미 X — 매 SSR 의 사용.

🧪 검증 / 중복

  • Verified (Next.js 15 docs, React Server Components RFC, Patterns.dev: rendering patterns 2026).
  • 신뢰도 A.

🕓 Changelog

날짜 변경
2026-05-08 Phase 1
2026-05-10 Manual cleanup — full spectrum (CSR/SSR/SSG/ISR/RSC), Next.js 15 patterns, decision matrix