Next.js SSR vs SSG vs ISR: 렌더링 전략 선택 가이드

“왜 홈페이지를 불러오는 데 3초나 걸리지?” 사장님은 화면을 바라보며 Chrome DevTools의 워터폴 차트를 보고 있었습니다. 빨간색 TTFB 막대가 뱀처럼 길게 늘어져 있었죠. 그때 저는 처음부터 렌더링 전략을 잘못 선택했을지도 모른다는 사실을 처음 깨달았습니다.
이런 사례는 드물지 않습니다. Next.js의 GitHub Issues에는 매일 “SSR과 SSG 중 무엇을 써야 하나요?”, “ISR을 설정했는데 왜 적용되지 않나요?” 같은 질문이 올라옵니다. 저도 예전에는 막막했습니다. 문서를 다 읽었는데도 실제 프로젝트를 만나면 어떤 전략을 골라야 할지 알기 어려웠습니다.
여러분도 비슷한 고민을 겪었을 수 있습니다.
- SSR을 사용했더니 초기 화면 로딩이 답답할 정도로 느립니다.
- SSG를 선택했더니 콘텐츠를 업데이트할 때마다 사이트 전체를 다시 빌드해야 합니다.
- ISR은 좋아 보이지만 설정을 마친 뒤에도 전혀 동작하지 않습니다.
사실 세 렌더링 전략 중 절대적으로 “가장 좋은” 것은 없고, 상황에 “가장 적합한” 전략만 있습니다. 이제 어떤 상황에서 어떤 전략을 써야 하는지, 흔한 함정을 어떻게 피하는지 확실히 알아보겠습니다.
먼저 알아보기: 세 가지 렌더링 전략이란?
어떤 전략을 선택할지 논의하기 전에 세 개념부터 분명히 정리해 보겠습니다. 최대한 쉽게 설명해 보겠습니다.
SSG(정적 사이트 생성): 미리 만들어 둔 도시락
매일 아침 도시락 100개를 미리 만들어 진열대에 놓아두는 도시락 가게를 상상해 보세요. 손님이 오면 바로 가져가기만 하면 됩니다. 이것이 SSG의 작동 방식입니다.
구체적으로 살펴보면 다음과 같습니다.
- 언제 생성하나요?
next build를 실행할 때 Next.js가 모든 페이지의 HTML을 미리 생성합니다. - 사용자가 방문하면 어떻게 되나요? CDN이 미리 생성된 HTML 파일을 바로 반환하므로 매우 빠릅니다.
- 언제 적합한가요? 기업 웹사이트, 제품 소개 페이지, 블로그 글처럼 콘텐츠가 자주 바뀌지 않는 페이지에 적합합니다.
장점은 분명합니다.
- 매우 빠릅니다. AWS 데이터에 따르면 SSG 페이지 로딩 속도는 SSR보다 40~60% 빠릅니다.
- TTFB(Time to First Byte)는 보통 50ms 이내입니다. Vercel도 공식적으로 측정한 수치입니다.
- 서버 부하가 거의 없어 트래픽이 많아져도 문제가 없습니다.
- 정적 파일 호스팅은 훨씬 저렴하므로 비용이 낮습니다.
하지만 한계도 있습니다.
- 콘텐츠가 업데이트되면 사이트 전체를 다시 빌드해야 합니다.
- 페이지가 많아질수록 빌드 시간이 길어져 수천 페이지라면 30분을 기다려야 할 수도 있습니다.
- 개인화된 콘텐츠를 지원하지 않아 모든 사용자가 같은 내용을 보게 됩니다.
결국 SSG는 “미리 준비하는 방식”으로 속도를 얻습니다.
SSR(서버 사이드 렌더링): 주문 즉시 조리
다시 도시락 가게를 떠올려 보세요. 이번에는 도시락을 미리 만들지 않습니다. 손님이 주문한 메뉴를 그 자리에서 조리합니다. 이것이 SSR입니다.
구체적으로 살펴보면 다음과 같습니다.
- 언제 생성하나요? 사용자가 요청할 때마다 서버가 HTML을 실시간으로 생성합니다.
- 사용자가 방문하면 어떻게 되나요? 서버가 데이터베이스를 조회하고 API를 호출해 HTML을 렌더링한 다음 반환할 때까지 기다립니다.
- 언제 적합한가요? 콘텐츠가 실시간으로 바뀌거나 개인화가 필요한 페이지에 적합합니다.
장점은 다음과 같습니다.
- 콘텐츠가 항상 최신 상태이며 사용자는 바로 지금의 데이터를 봅니다.
- 사용자의 Cookie나 권한에 따라 다른 콘텐츠를 표시하는 개인화를 지원합니다.
- 요청 헤더나 쿼리 매개변수처럼 요청 시점에만 알 수 있는 정보에 접근할 수 있습니다.
하지만 대가도 만만치 않습니다.
- 느립니다. Vercel 공식 데이터에 따르면 TTFB는 보통 200~500ms입니다.
- 서버 부하가 크고 트래픽이 급증하면 서버가 버티지 못할 수 있습니다.
- 서버를 항상 실행해야 하므로 비용이 많이 듭니다.
실제 사례가 있습니다. 한 전자상거래 사이트는 SSR을 사용할 때 초기 화면 로딩에 2.3초가 걸렸습니다. 이후 ISR로 바꾸자 0.8초까지 줄었습니다.
ISR(증분 정적 재생성): 도시락과 주문 조리의 혼합 방식
이번에는 조금 더 영리한 방법을 써봅니다. 도시락을 미리 만들어 두되 일정한 간격, 예를 들어 한 시간마다 새로 만듭니다. 손님은 대부분 미리 만든 도시락을 받지만 내용이 지나치게 오래되지는 않습니다. 이것이 ISR입니다.
구체적으로 살펴보면 다음과 같습니다.
- 최초 빌드:
next build를 실행할 때 SSG처럼 정적 HTML을 생성합니다. - 이후 업데이트: 설정한
revalidate시간에 따라 백그라운드에서 페이지를 자동으로 다시 생성합니다. - 사용자가 방문하면 어떻게 되나요? 대부분 캐시된 HTML을 빠르게 반환하며, 만료된 경우 백그라운드에서 갱신합니다.
ISR은 균형점입니다.
- 사용자가 정적 파일을 받으므로 SSG의 속도를 갖췄습니다.
- 콘텐츠를 주기적으로 업데이트하므로 SSR의 최신성도 갖췄습니다.
- 사이트 전체를 매번 다시 빌드할 필요가 없습니다.
설정은 간단합니다(App Router 문법).
// app/posts/[id]/page.tsx
export const revalidate = 60; // 60초 후 재검증
export default async function Post({ params }) {
const post = await getPost(params.id);
return <div>{post.content}</div>;
}
다만 몇 가지 함정이 있습니다.
- 설정이 적용되지 않나요? 개발 환경(
next dev)에서 테스트했을 수 있습니다. ISR은 프로덕션 환경(next build+next start)에서만 동작합니다. - 배포 플랫폼이 지원하지 않나요? Vercel은 기본 지원하지만 다른 플랫폼은 추가 설정이 필요할 수 있습니다.
솔직히 말해 ISR은 제가 지금 가장 자주 사용하는 전략입니다. SSG와 SSR 각각의 문제를 해결해 주기 때문에 정말 유용합니다.
의사결정 트리: 어떤 상황에 어떤 전략을 써야 할까?
개념은 정리됐습니다. 이제 가장 중요한 질문을 살펴보겠습니다. 내 프로젝트에는 어떤 전략을 써야 할까요?
걱정하지 마세요. 프로젝트 상황과 하나씩 대조해 볼 수 있도록 의사결정 과정을 정리했습니다.
첫 번째 단계: 세 가지 질문을 던져보세요
질문 1: 콘텐츠를 개인화해야 하나요?
사용자의 신원, 권한, 선호도에 따라 페이지에 서로 다른 콘텐츠를 표시해야 한다면 바로 SSR을 사용하세요.
대표적인 상황은 다음과 같습니다.
- 사용자 대시보드(사람마다 보는 데이터가 다름)
- 개인 프로필 페이지
- 장바구니 페이지
- 인증 후에만 접근할 수 있는 모든 페이지
왜 그럴까요? 개인화 콘텐츠는 미리 생성할 수 없고 사용자가 요청할 때 동적으로 만들어야 하기 때문입니다.
질문 2: 콘텐츠가 얼마나 자주 업데이트되나요?
이 질문에 대한 답이 SSG와 ISR 중 무엇을 쓸지 결정합니다.
-
몇 초에서 몇 분마다 업데이트: SSR을 사용합니다.
- 주식 시세, 스포츠 경기 점수, 채팅 메시지 등이 해당합니다.
- 실시간성이 중요한 콘텐츠에는 SSR이 유일한 선택입니다.
-
몇 분에서 몇 시간마다 업데이트: ISR을 사용합니다.
- 뉴스 사이트, 블로그 홈페이지, 제품 목록, 전자상거래 재고 등이 해당합니다.
- ISR에
revalidate: 300(5분)을 설정하면 빠른 속도와 최신성을 모두 얻을 수 있습니다.
-
거의 업데이트되지 않거나 수동으로 업데이트: SSG를 사용합니다.
- 기업 웹사이트, 제품 소개 페이지, 도움말 문서 등이 해당합니다.
- 이런 콘텐츠는 몇 주 또는 몇 달에 한 번만 수정될 수 있습니다.
질문 3: 트래픽은 얼마나 많은가요?
트래픽 규모는 비용과 성능을 고려할 때 영향을 줍니다.
-
매우 높은 트래픽(하루 수백만 PV): SSG나 ISR을 우선합니다.
- 정적 파일은 CDN에서 바로 제공할 수 있어 비용이 낮고 성능이 좋습니다.
- SSR을 쓰면 서버 부하와 비용이 크게 증가합니다.
-
중간 또는 낮은 트래픽: 세 방식 모두 사용할 수 있습니다.
- 콘텐츠의 실시간성이 중요하다면 SSR도 충분히 괜찮습니다.
- 하지만 ISR로 해결할 수 있다면 사용하지 않을 이유가 있을까요?
두 번째 단계: 자주 쓰이는 상황 빠른 참조표
대표적인 상황을 정리했습니다. 자신의 프로젝트에 맞는 항목을 바로 찾아보세요.
SSG를 사용하는 상황:
- ✅ 기업 웹사이트
- ✅ 제품 소개 페이지와 가격 페이지
- ✅ 마케팅 랜딩 페이지
- ✅ 블로그 글 상세 페이지(게시 후 수정하지 않는 콘텐츠)
- ✅ 기술 문서와 API 문서
- ✅ 도움말 센터와 FAQ
핵심 키워드를 기억하세요. 정적, 공개, 낮은 업데이트 빈도입니다.
SSR을 사용하는 상황:
- ✅ 소셜 미디어 피드(Facebook, Twitter 방식)
- ✅ 사용자 개인 대시보드
- ✅ 장바구니와 주문 페이지
- ✅ 실시간 데이터 패널
- ✅ 검색 결과 페이지(쿼리 매개변수에 따라 생성)
- ✅ 인증이 필요한 페이지(Cookie 기반 판단)
핵심 키워드는 동적, 개인화, 실시간입니다.
ISR을 사용하는 상황(제가 가장 좋아하는 방식):
- ✅ 블로그 홈페이지와 글 목록(새 글이 주기적으로 추가됨)
- ✅ 뉴스 사이트
- ✅ 전자상거래 제품 상세 페이지(가격과 재고가 주기적으로 업데이트됨)
- ✅ 포럼 게시글 페이지(댓글과 좋아요 수가 몇 분 늦게 업데이트되어도 괜찮음)
- ✅ UGC 콘텐츠 플랫폼(자주 업데이트되지만 초 단위 실시간성은 필요 없음)
- ✅ 일기 예보와 환율 정보
핵심 키워드는 주기적 업데이트, 허용 가능한 지연, 높은 트래픽입니다.
세 번째 단계: 혼합 사용이 가장 좋습니다
한 가지 오해부터 바로잡겠습니다. 사이트 전체에서 하나의 전략만 사용할 필요는 없습니다.
실제로 대부분의 프로젝트는 여러 전략을 함께 사용합니다.
- 홈페이지와 제품 목록에는 ISR을 사용합니다(트래픽이 많고 콘텐츠가 주기적으로 업데이트됨).
- 제품 상세 페이지에는 SSG(콘텐츠가 안정적임) 또는 ISR(가격과 재고가 바뀜)을 사용합니다.
- 사용자 대시보드에는 SSR을 사용합니다(개인화됨).
- 회사 소개와 문의 페이지에는 SSG를 사용합니다(완전한 정적 콘텐츠).
저희 팀의 한 전자상거래 프로젝트도 이렇게 구성했습니다.
- 홈페이지(ISR, 10분마다 업데이트)
- 상품 목록(ISR, 5분마다 업데이트)
- 상품 상세(ISR, 재고가 바뀌므로 3분마다 업데이트)
- 장바구니(SSR, 실시간 필수)
- 사용자 센터(SSR, 개인화)
- 회사 소개와 개인정보 처리방침(SSG, 거의 변경되지 않음)
이렇게 조합하면 성능과 실시간성을 모두 확보할 수 있습니다.
한 문장으로 기억하는 결정 공식
아직 확신이 없다면 다음 문장을 기억하세요.
정적 콘텐츠에는 SSG, 실시간 콘텐츠에는 SSR, 주기적으로 업데이트되는 콘텐츠에는 ISR
확신이 없다면 ISR부터 사용해 보세요. 세 전략 중 가장 균형 잡힌 선택이며 잘못 선택할 가능성도 가장 낮습니다.
흔한 세 가지 함정과 해결 방법
이론을 살펴봤으니 이제 실무 이야기를 해보겠습니다. 저도 다음 세 가지 함정을 모두 경험했고, 여러분도 마주칠 가능성이 높습니다.
함정 1: ISR의 revalidate가 적용되지 않음
증상: 기대에 차서 revalidate: 60을 설정하고 페이지가 1분마다 업데이트될 것으로 생각했지만 아무리 기다려도 콘텐츠가 그대로입니다.
제가 겪은 좌절: 정말로 처음 ISR을 썼을 때 이 문제에 이틀 내내 붙잡혀 있었습니다. 수많은 문서를 찾아보고 설정을 여러 번 바꿨는데도 동작하지 않았습니다.
원인은 세 가지입니다.
-
개발 환경에서 ISR을 지원하지 않음
가장 흔한 원인입니다.
next dev개발 모드에서는 ISR이 전혀 동작하지 않습니다. 프로덕션 모드에서만 작동합니다.해결 방법:
# next dev로 ISR을 테스트하지 마세요 # 먼저 빌드한 다음 시작해야 합니다 npm run build npm run start # 그다음 페이지에 접속해 테스트합니다 -
배포 플랫폼이 지원하지 않음
모든 플랫폼이 ISR을 기본 지원하는 것은 아닙니다. Vercel은 Next.js를 만든 회사인 만큼 잘 지원하지만, 다른 플랫폼은 추가 설정이 필요할 수 있습니다.
Netlify의 경우: ISR을 지원하려면
@netlify/plugin-nextjs플러그인을 설치해야 합니다.확인 방법: 사용하는 배포 플랫폼 문서에서 “Next.js ISR support”를 검색하세요.
-
CDN 캐시가 ISR을 덮어씀
Next.js 앞에 Cloudflare 같은 CDN이나 리버스 프록시를 추가했다면 전체 응답을 캐시해 ISR 갱신 메커니즘이 동작하지 않을 수 있습니다.
해결 방법: CDN이
Cache-Control헤더를 따르도록 설정하거나 ISR 페이지의 CDN 캐시 시간을 짧게 설정하세요.
제안: ISR을 설정한 뒤에는 반드시 프로덕션 환경에서 테스트하세요. console.log(new Date())로 페이지 생성 시간을 출력하면 revalidate가 적용되는지 확인할 수 있습니다.
함정 2: 견디기 어려울 정도로 느린 SSR 초기 화면 로딩
증상: SSR을 적용한 뒤 첫 화면이 2~3초 동안 비어 있어 사용자가 떠날 지경입니다.
실제 사례: 저희 프로젝트 하나는 홈페이지에서 SSR을 사용해 사용자 정보와 추천 콘텐츠를 가져왔습니다. 그 결과 첫 화면 TTFB가 1.2초까지 늘었고 렌더링 시간까지 더해져 사용자가 콘텐츠를 보려면 3초를 기다려야 했습니다. 사장님의 표정은 좋지 않았습니다.
원인 분석:
SSR이 느린 이유는 대체로 서버 측 데이터 조회가 느리기 때문입니다. 원인은 다음과 같을 수 있습니다.
- API 호출이 느림(외부 API 지연 시간이 큼)
- 데이터베이스 쿼리가 느림(인덱스가 없거나 쿼리가 복잡함)
- 요청을 직렬로 처리함(한 인터페이스가 다른 인터페이스를 기다림)
- 서버 성능이 낮거나 지리적으로 멀리 있음
해결 방법은 네 가지입니다.
-
Streaming SSR과 Suspense 사용(React 18+)
모든 데이터를 받은 뒤 렌더링하지 말고 페이지 뼈대를 먼저 반환한 다음 데이터가 준비되면 스트리밍하세요.
// app/dashboard/page.tsx import { Suspense } from 'react'; export default function Dashboard() { return ( <div> <h1>사용자 대시보드</h1> {/* 빠르게 렌더링되는 부분 */} <UserInfo /> {/* 느린 데이터는 Suspense로 감쌉니다 */} <Suspense fallback={<div>통계 데이터 불러오는 중...</div>}> <SlowStats /> </Suspense> </div> ); }이렇게 하면 사용자가 페이지를 더 빨리 볼 수 있어 경험이 훨씬 좋아집니다.
-
데이터 병렬 요청
여러 API 호출을 병렬로 실행하세요.
// ❌ 직렬: 느림 const user = await getUser(); const posts = await getPosts(user.id); // ✅ 병렬: 빠름 const [user, posts] = await Promise.all([ getUser(), getPosts() ]); -
ISR 전환 고려
SSR이 필요하다고 생각했지만 사실 ISR이면 충분한 경우가 많습니다.
스스로 물어보세요. 이 페이지의 데이터가 정말 실시간이어야 할까요? 1분 늦게 업데이트되어도 괜찮다면 ISR을 사용하세요.
앞에서 언급한 홈페이지는 나중에 ISR(
revalidate: 60)로 바꿨고, 초기 화면 로딩 시간이 3초에서 0.7초로 줄었습니다. -
Edge에 배포
Vercel을 사용한다면 Edge Functions를 시도해 보세요. SSR 함수를 전 세계 CDN 노드에 배포하므로 사용자와 더 가까워지고 지연 시간이 줄어듭니다.
// app/api/data/route.ts export const runtime = 'edge'; // 이 한 줄이면 됩니다
함정 3: 너무 긴 SSG 빌드 시간
증상: 웹사이트에 수천 개의 페이지가 있어 next build를 실행할 때마다 20~30분을 기다려야 하며 시간 초과로 실패하기도 합니다.
문제가 두드러지는 상황: 전자상거래 사이트에 상품 5,000개가 있고 블로그에 글 3,000개가 있다면 SSG는 빌드 시 각 페이지의 HTML을 생성해야 합니다.
느린 이유:
SSG는 빌드할 때 모든 페이지의 HTML을 생성합니다. 페이지가 많을수록 빌드 시간이 길어집니다. 게다가 롱테일 상품이나 오래된 글처럼 아무도 방문하지 않을 수 있는 페이지도 많습니다.
해결 방법:
-
fallback 전략 사용
모든 페이지를 한꺼번에 만들지 말고 인기 페이지들만 생성하며 나머지는 요청 시 생성하세요.
// app/posts/[id]/page.tsx export async function generateStaticParams() { // 인기 글 100개만 반환합니다 const posts = await getTopPosts(100); return posts.map(post => ({ id: post.id })); } // 나머지 페이지는 처음 방문할 때 생성합니다 export const dynamicParams = true; -
ISR과 결합
빌드 시에는 홈페이지와 인기 페이지들만 생성하고 나머지는 ISR로 요청 시 생성하세요.
이렇게 하면 빌드 시간이 크게 줄고, 캐시가 있으므로 사용자 방문 속도도 느려지지 않습니다.
-
증분 빌드(Incremental Builds)
Vercel은 변경된 페이지들만 다시 빌드하는 증분 빌드를 지원합니다. 글 하나를 업데이트하더라도 사이트 전체를 다시 빌드할 필요가 없습니다.
다른 플랫폼에서는 이 로직을 직접 구현해야 할 수 있습니다.
실제 효과:
저희 블로그 프로젝트 하나에는 글이 2,000개 있었습니다. 처음에는 순수 SSG를 사용해 빌드에 15분이 걸렸습니다. 이후 다음과 같이 바꿨습니다.
- 빌드 시 최신 글 50개만 생성
- 나머지 글은
dynamicParams = true로 요청 시 생성 - 모든 글 페이지에 ISR 적용(
revalidate: 3600)
이제 빌드 시간은 2분으로 줄었고 사용자의 페이지 접근 속도도 느려지지 않았습니다.
Next.js 15의 새로운 기능: React Server Components와 PPR
여기까지 살펴본 김에 Next.js 15에 추가된 두 가지 기능도 이야기해 보겠습니다. 두 기능은 완전한 “렌더링 전략”은 아니지만 페이지를 만드는 방식에 분명한 영향을 줍니다.
React Server Components(RSC): 컴포넌트 단위 SSR
Next.js 13+의 App Router를 사용했다면 이미 Server Components를 사용하고 있습니다.
기존 SSR과 무엇이 다를까요?
- 기존 SSR: 페이지 전체를 서버에서 렌더링합니다.
- RSC: 기본적으로 컴포넌트를 서버에서 렌더링하며 상호작용이 필요한 컴포넌트만 클라이언트에서 실행합니다.
장점은 분명합니다.
-
JS bundle이 작아집니다
Server Component 코드는 클라이언트 번들에 포함되지 않습니다. Next.js 공식 데이터에 따르면 RSC를 사용하면 클라이언트 JavaScript 크기를 30~50% 줄일 수 있습니다.
페이지 로딩이 더 빨라지고 사용자의 휴대전화도 덜 뜨거워집니다.
-
백엔드 리소스에 직접 접근할 수 있습니다
Server Component는 별도의 API 엔드포인트 없이 데이터베이스를 직접 조회하고 파일 시스템을 읽을 수 있습니다.
// app/posts/page.tsx // Server Component이므로 데이터베이스를 직접 조회할 수 있습니다 async function getPosts() { const posts = await db.posts.findMany(); return posts; } export default async function PostsPage() { const posts = await getPosts(); return ( <div> {posts.map(post => ( <PostCard key={post.id} post={post} /> ))} </div> ); }
실전 제안:
- 기본적으로 Server Component를 사용하세요(App Router에서는 이것이 기본값입니다).
- 상호작용이 필요한 곳에만 Client Component를 사용하세요(
'use client'추가). - 데이터 조회와 정적 UI에는 Server Component를, 버튼·폼·애니메이션에는 Client Component를 사용하세요.
이렇게 하면 애플리케이션이 SSR의 SEO 장점과 작은 JS bundle을 모두 갖출 수 있습니다.
Partial Prerendering(PPR): 정적 영역과 동적 영역의 결합
PPR은 Next.js 15에 도입된 실험적 기능으로, 하나의 페이지에서 정적 영역과 동적 영역을 함께 사용할 수 있게 합니다.
예를 들어 보겠습니다.
전자상거래 제품 페이지는 다음처럼 나눌 수 있습니다.
- 제품 설명과 이미지(정적, 빌드 시 생성)
- 재고와 가격(동적, 요청 시 조회)
PPR을 사용하면 정적 영역은 빌드할 때 미리 생성하고 동적 영역만 요청 시 계산합니다. 그 결과 속도와 최신성을 모두 얻을 수 있습니다.
사용 방법:
// next.config.js
module.exports = {
experimental: {
ppr: true,
},
};
// app/products/[id]/page.tsx
export const experimental_ppr = true;
export default function ProductPage({ params }) {
return (
<div>
{/* 정적 영역: 빌드 시 생성 */}
<ProductDescription id={params.id} />
{/* 동적 영역: 요청 시 생성 */}
<Suspense fallback={<div>불러오는 중...</div>}>
<DynamicStock id={params.id} />
</Suspense>
</div>
);
}
하지만 중요한 전제가 있습니다.
PPR은 아직 실험적 기능이므로 프로덕션 환경에서 사용하는 것은 권장하지 않습니다. 중요하지 않은 페이지에서 시험해 볼 수는 있지만 사이트 전체에 적용하지는 마세요.
안정화되면(어쩌면 Next.js 16에서) 매우 강력한 기능이 될 것입니다.
이 새로운 기능들을 SSR/SSG/ISR과 어떻게 결합할 수 있을까?
- RSC + SSG: Server Component는 기본적으로 정적이므로 SSG와 매우 잘 맞습니다.
- RSC + ISR: Server Component +
revalidate로 정적 속도와 주기적 갱신을 모두 제공합니다. - RSC + SSR: 동적 라우트를 사용하거나
dynamic = 'force-dynamic'을 설정하면 SSR이 됩니다. - PPR: SSG와 SSR의 궁극적인 결합으로 볼 수 있습니다.
제 생각에 RSC는 Next.js의 기반 아키텍처를 개선한 것이고 SSG/SSR/ISR은 이 아키텍처를 바탕으로 한 렌더링 전략입니다. 서로 충돌하지 않고 오히려 보완합니다.
결론
많은 내용을 살펴봤으니 처음 질문으로 돌아가 보겠습니다. SSR, SSG, ISR 중 무엇을 선택해야 할까요?
사실 정답은 없습니다. 프로젝트마다 요구 사항, 트래픽, 예산이 다릅니다. 하지만 다음 세 가지 핵심 질문에 답할 수 있다면 선택은 어렵지 않습니다.
- 콘텐츠를 개인화해야 하나요? → 그렇다면 SSR을 사용하세요.
- 콘텐츠가 얼마나 자주 업데이트되나요? → 실시간 콘텐츠에는 SSR, 주기적 업데이트에는 ISR, 거의 변하지 않는 콘텐츠에는 SSG를 사용하세요.
- 트래픽은 얼마나 많은가요? → 트래픽이 매우 많다면 SSG나 ISR을 우선하세요.
글 도입부에서 사장님이 “왜 이렇게 느리지?”라고 물었던 장면을 기억하시나요? 이후 저희는 그 홈페이지를 SSR에서 ISR(revalidate: 60)로 바꾸었고 초기 화면 로딩 시간을 3초에서 0.8초로 줄였습니다. 사장님도 만족했고 사용자 경험도 좋아졌습니다.
제안은 다음과 같습니다.
- 확신이 없다면 먼저 ISR을 사용해 보세요. 세 방식 중 가장 균형이 잘 잡혀 있어 빠르면서 콘텐츠의 최신성도 유지할 수 있습니다.
- 프로젝트를 출시한 뒤 Chrome DevTools의 Performance 패널로 TTFB와 FCP 같은 지표를 직접 측정하세요.
- 페이지마다 서로 다른 전략을 사용할 수 있으므로 하나만 고집하지 마세요.
마지막으로 렌더링 전략은 영원히 고정되는 것이 아닙니다. 프로젝트가 성장하고 사용자 수와 요구 사항이 바뀌면 전략도 조정할 수 있습니다. 변경을 두려워하지 마세요. Next.js에서 전략을 전환하는 비용은 생각보다 낮습니다.
이 글이 시행착오를 줄이는 데 도움이 되길 바랍니다. 실전 경험이나 문제를 겪은 이야기가 있다면 댓글로 공유해 주세요!
FAQ
SSR, SSG, ISR의 핵심 차이는 무엇인가요?
언제 SSG, SSR, ISR을 사용해야 하나요?
ISR의 revalidate 설정이 적용되지 않는 이유는 무엇인가요?
SSR의 초기 화면 로딩이 느릴 때는 어떻게 해야 하나요?
SSG 빌드 시간이 너무 길 때는 어떻게 해야 하나요?
서로 다른 렌더링 전략을 함께 사용할 수 있나요?
React Server Components와 SSR/SSG/ISR은 어떤 관계인가요?
3분 읽기 · 게시일: 2025년 12월 19일 · 수정일: 2026년 9월 4일
Next.js 완전 가이드
검색으로 들어왔다면 같은 시리즈의 이전 글이나 다음 글로 이동하는 것이 가장 빠릅니다.
이전
Next.js Server Components 데이터 가져오기 완벽 가이드: fetch, 데이터베이스 쿼리와 모범 사례
Next.js Server Components에서 데이터를 가져오는 방법을 정리한 완벽 가이드입니다. fetch와 데이터베이스 쿼리 선택, async/await 작성법, 캐시 전략, 오류 처리 모범 사례와 흔한 함정을 설명합니다.
45편 중 6편
다음
Next.js Server Actions로 폼 처리와 검증 구현하기
Next.js Server Actions로 폼을 처리하는 방법부터 Zod 검증, 보안 점검, 로딩 상태와 낙관적 업데이트까지 실제 코드로 설명합니다.
45편 중 8편



댓글
GitHub로 로그인하여 댓글을 남기세요