Search

04-5_ISR

증분 정적 재생성 (ISR)

ISR(Incremental Static Regeneration)은 SSG의 장점은 유지하면서 단점을 보완해요. 핵심 아이디어는:
1.
처음 요청 시 렌더링하고 캐시에 저장
2.
이후 요청은 캐시된 HTML 반환 (빠름)
3.
일정 시간이 지나면 백그라운드에서 재생성

직접 구현해보기

// server.ts import { Hono } from "hono"; import { renderToString } from "react-dom/server"; import BlogPost from "./pages/BlogPost"; const app = new Hono(); // 캐시 저장소 const cache = new Map<string, { html: string; timestamp: number }>(); const REVALIDATE_SECONDS = 60; // 60초마다 재검증 app.get("/blog/:id", async (c) => { const id = c.req.param("id"); const cacheKey = `/blog/${id}`; const now = Date.now(); // 1. 캐시 확인 const cached = cache.get(cacheKey); if (cached) { const age = (now - cached.timestamp) / 1000; if (age < REVALIDATE_SECONDS) { // 캐시가 신선함 → 그대로 반환 return c.html(cached.html); } // 캐시가 오래됨 → 일단 반환하고, 백그라운드에서 재생성 regenerateInBackground(cacheKey, id); return c.html(cached.html); } // 2. 캐시 없음 → 새로 렌더링 const html = await renderPage(id); cache.set(cacheKey, { html, timestamp: now }); return c.html(html); }); async function renderPage(id: string) { const post = await fetchPost(id); const content = renderToString(<BlogPost post={post} />); return ` <!DOCTYPE html> <html> <body> <div id="root">${content}</div> <script> window.__INITIAL_DATA__ = ${JSON.stringify(post)}; </script> <script type="module" src="/client.tsx"></script> </body> </html> `; } function regenerateInBackground(cacheKey: string, id: string) { // 백그라운드에서 재생성 (요청을 블로킹하지 않음) setImmediate(async () => { const html = await renderPage(id); cache.set(cacheKey, { html, timestamp: Date.now() }); console.log(`[ISR] ${cacheKey} 재생성 완료`); }); }
TypeScript
복사

ISR의 동작 흐름

[첫 번째 요청] /blog/hello → 캐시 없음 → 렌더링 → 캐시 저장 → 응답 [두 번째 요청] (30초 후) → 캐시 있음 (30초 < 60초) → 캐시된 HTML 응답 [세 번째 요청] (70초 후) → 캐시 있음 (70초 > 60초, stale) → 캐시된 HTML 응답 (사용자는 기다리지 않음) → 백그라운드에서 재생성 시작 [네 번째 요청] (71초 후) → 새로 생성된 캐시 응답
Plain Text
복사
stale-while-revalidate 패턴이에요. 오래된 캐시라도 일단 빠르게 응답하고, 백그라운드에서 갱신해요.

SSR vs SSG vs ISR

방식
렌더링 시점
장점
단점
SSR
매 요청
항상 최신 데이터
서버 부하
SSG
빌드 시
가장 빠름
업데이트 어려움
ISR
첫 요청 + 주기적
빠름 + 업데이트
구현 복잡
어떤 방식이 좋은지는 페이지 특성에 따라 달라요:
실시간 데이터 (주식, 채팅) → SSR
거의 안 바뀌는 콘텐츠 (문서, 블로그) → SSG
가끔 바뀌는 콘텐츠 (상품 목록, 뉴스) → ISR