{post.title}
{post.date}
React로 프로젝트를 하다가 Next.js를 알게 됨 "React랑 뭐가 다르지?" 싶었는데, Next.js는 프레임워크라고 함 찾아보니 SSR, SSG, ISR 같은 렌더링 방식이 있더라 특히 SSR과 SSG가 뭐가 다른지 헷갈렸음 그래서 Next.js가 뭐고, SSR과 SSG의 차이를 정리해봄
Next.js는 React 기반의 풀스택 프레임워크 클라이언트 사이드만 하던 React에서 한 걸음 나아가서 서버 사이드도 처리할 수 있게 해줌
React vs Next.js
React는 클라이언트에서 모든 렌더링을 함
브라우저 → 빈 HTML 받음 → JavaScript 실행 → 화면 렌더링
Next.js는 서버에서도 렌더링할 수 있음
브라우저 → 완성된 HTML 받음 → JavaScript 실행 → 상호작용
웹 페이지를 렌더링하는 방식은 크게 3가지
1. Client Side Rendering (CSR) - React 기본
유저가 접속 → 빈 HTML 다운로드
→ JavaScript 다운로드 및 실행
→ 브라우저에서 렌더링
장점: 개발이 간단, 상호작용이 빠름 단점: 초기 로딩이 느림, SEO가 안 좋음
2. Server Side Rendering (SSR) - Next.js 지원
유저가 접속 → 서버에서 렌더링
→ 완성된 HTML 전송
→ 브라우저에서 표시 (JavaScript 실행)
장점: 초기 로딩이 빠름, SEO가 좋음 단점: 서버 부하 증가, 동적 콘텐츠마다 렌더링 필요
3. Static Site Generation (SSG) - Next.js 지원
빌드 시점 → 서버에서 미리 렌더링
→ 정적 HTML 파일로 저장
유저가 접속 → 이미 만들어진 HTML 전송 (매우 빠름)
장점: 가장 빠름, SEO 좋음, 서버 부하 없음 단점: 미리 빌드해야 함, 동적 콘텐츠에 부적합
SSR은 요청이 올 때마다 서버에서 렌더링해서 완성된 HTML을 보냄
SSR 예시
// pages/products/[id].js
export default function Product({ product }) {
return (
가격: {product.price}원
설명: {product.description}
);
}
// 서버에서 실행됨
export async function getServerSideProps(context) {
const { id } = context.params;
// 서버에서 데이터 조회
const response = await fetch(`https://api.example.com/products/${id}`);
const product = await response.json();
return {
props: {
product
},
revalidate: 60 // 60초마다 재검증 (ISR)
};
}
SSR의 흐름:
SSR 사용 시점:
SSR의 문제점:
// 매 요청마다 이 함수가 실행됨
export async function getServerSideProps() {
const data = await fetch('...'); // 매번 API 호출
return { props: { data } };
}
1000명이 동시에 접속하면 1000번 API 호출 → 서버 부하 증가
SSG는 빌드 타임에 미리 렌더링해서 정적 HTML 파일로 저장
SSG 예시
// pages/blog/[slug].js
export default function BlogPost({ post }) {
return (
{post.date}
);
}
// 빌드 시점에 실행됨
export async function getStaticProps(context) {
const { slug } = context.params;
// 빌드 타임에 데이터 조회
const response = await fetch(`https://api.example.com/posts/${slug}`);
const post = await response.json();
return {
props: {
post
},
revalidate: 3600 // 1시간마다 재생성 (ISR)
};
}
// 어떤 경로를 미리 생성할지 정의
export async function getStaticPaths() {
const response = await fetch('https://api.example.com/posts');
const posts = await response.json();
const paths = posts.map(post => ({
params: { slug: post.slug }
}));
return {
paths,
fallback: 'blocking' // 없는 경로는 요청시 생성
};
}
SSG의 흐름:
SSG 사용 시점:
SSG의 장점:
// 빌드 시점에만 API 호출
// 1000명이 접속해도 API 호출 0번 → 서버 부하 없음
// CDN에 캐시되면 전 세계에서 매우 빠르게 제공
SSR과 SSG의 장점을 합친 방식
export async function getStaticProps() {
const data = await fetch('...');
return {
props: { data },
revalidate: 60 // 60초마다 백그라운드에서 재생성
};
}
처음에는 정적 HTML 제공 (빠름) 60초마다 백그라운드에서 새로 렌더링 업데이트된 콘텐츠는 다음 요청부터 제공
항목 SSR SSG
| 렌더링 시점 | 요청 시점 | 빌드 시점 |
| 속도 | 보통 (API 호출 필요) | 매우 빠름 |
| SEO | 좋음 | 좋음 |
| 서버 부하 | 높음 | 없음 |
| 데이터 신선도 | 항상 최신 | 재빌드까지 구식 |
| 사용 사례 | 실시간 데이터 | 정적 콘텐츠 |
| 예시 | SNS 피드, 마이페이지 | 블로그, 문서 |
SSG 써야 할 때:
// 블로그 글, 문서, FAQ
// 자주 바뀌지 않는 상품 정보
// 변경 빈도: 하루 수 번 정도
export async function getStaticProps() {
const posts = await getAllBlogPosts();
return {
props: { posts },
revalidate: 3600 // 1시간마다 재생성
};
}
SSR 써야 할 때:
// 실시간 주가, 주문 상태
// 유저별 개인화 콘텐츠
// 변경 빈도: 실시간
export async function getServerSideProps(context) {
const userId = context.req.user.id;
const userData = await getUserData(userId);
return { props: { userData } };
}
둘 다 섞어야 할 때:
// 상품 목록: SSG (자주 안 바뀜)
// 재고 정보: SSR (자주 바뀜)
// 사용자 리뷰: SSR (실시간)
Next.js는 React로 만든 웹앱을 한 단계 업그레이드할 수 있게 해줌
SSR은 매번 서버에서 렌더링 → 항상 최신 데이터, 하지만 느릴 수 있음 SSG는 빌드할 때 미리 렌더링 → 매우 빠르지만, 미리 빌드해야 함 ISR은 둘의 장점을 합쳐서 → 빠르면서도 주기적으로 업데이트
처음엔 어떤 방식을 써야 할지 헷갈리지만, 데이터의 변경 빈도를 기준으로 생각하면 쉬움 자주 안 바뀌면 SSG, 자주 바뀌면 SSR!
앞으로 Next.js로 프로젝트 할 때 이 3가지 방식을 상황에 맞게 잘 섞어서 써봐야겠음!
| (Next.js) CSR vs SSR (1) | 2025.11.26 |
|---|---|
| (Next.js) 서버 컴포넌트 + 클라이언트 상태 관리 전략 (0) | 2025.11.12 |
| (Next.js) npm run dev와 npm start 차이 (4) | 2025.01.09 |
| (Next.js) PWA 구현 (4) | 2025.01.07 |