웹을 개발하다 보면 SPA, CSR, SSR, SSG, ISR, PWA 같은 용어를 자주 접한다.
겉보기엔 비슷하지만, “언제”와 “어디서” 페이지를 렌더링하느냐에 따라 완전히 다르다.
이 글에서는 이 개념들을 하나의 흐름으로 정리한다.
한 개의 HTML로 시작해 화면을 동적으로 교체하는 웹앱 구조.
초기에 /index.html 한 장만 불러오고, 이후 라우팅은 브라우저가 직접 처리한다.
SPA는 구조 개념이다. 실제 화면은 CSR, SSR, ISR 등의 렌더링 방식으로 표시된다.
브라우저에서 JS가 HTML을 그리는 방식.
서버는 빈 HTML + JS만 내려주고, 브라우저가 JS 실행 후 데이터를 불러와 화면을 만든다.
| 항목 | 내용 |
|---|---|
| 렌더링 위치 | 브라우저 |
| HTML 생성 시점 | 클라이언트 실행 시 |
| 서버 필요 여부 | ❌ 정적 파일만으로 가능 |
| 초기 속도 | 느림 (JS 실행 후 표시) |
| SEO | 약함 |
| 대표 예시 | CRA(Create React App), Vue CLI |
대부분의 SPA는 CSR 기반으로 동작한다.
요청이 들어올 때마다 서버가 HTML을 완성해서 전달.
브라우저는 이미 렌더링된 HTML을 즉시 표시한다.
| 항목 | 내용 |
|---|---|
| 렌더링 위치 | 서버 |
| HTML 생성 시점 | 요청 시마다 |
| 서버 필요 여부 | ✅ 필요 |
| 초기 속도 | 빠름 |
| SEO | 강함 |
| 대표 예시 | Next.js, Nuxt.js |
장점
단점
SSR은 매 요청마다 서버가 페이지를 다시 그린다. 즉 “주문 즉시 조리” 방식이다.
배포 전에 HTML을 미리 만들어두는 방식.
사용자가 접속하면 이미 생성된 정적 HTML이 즉시 제공된다.
| 항목 | 내용 |
|---|---|
| 렌더링 위치 | 빌드 서버 |
| HTML 생성 시점 | 빌드 시점 |
| 서버 필요 여부 | ❌ 불필요 |
| 초기 속도 | 매우 빠름 |
| SEO | 강함 |
| 대표 예시 | Gatsby, Next.js(SSG), Astro |
장점
단점
“미리 조리해 냉장고에 넣어둔 요리”와 같다.
SSG의 단점을 개선한 방식.
기본적으로는 정적 페이지를 제공하지만, 일정 시간마다 백그라운드에서 새 HTML을 생성한다.
| 항목 | 내용 |
|---|---|
| 렌더링 위치 | 빌드 + 플랫폼 백엔드 |
| HTML 생성 시점 | 초기 빌드 + 주기적 재생성 |
| 서버 필요 여부 | ⚙️ 플랫폼 지원(Vercel 등) |
| 초기 속도 | SSG 수준으로 빠름 |
| SEO | 강함 |
| 데이터 최신성 | 주기적 갱신 가능 |
장점
단점
“냉장고 음식이 일정 시간이 지나면 자동으로 새로 조리되는 구조”와 같다.
// SSR
export async function getServerSideProps() {
const data = await fetch(...);
return { props: { data } };
}
// SSG
export async function getStaticProps() {
const data = await fetch(...);
return { props: { data } };
}
// ISR
export async function getStaticProps() {
const data = await fetch(...);
return { props: { data }, revalidate: 60 }; // 60초마다 새로 생성
}
렌더링 방식이 아니라, 웹을 설치형 앱처럼 만드는 기술 세트.
핵심 구성
manifest.json — 앱 이름, 아이콘, 시작화면 지정service worker — 캐시, 오프라인, 푸시 기능 담당장점
단점
PWA는 CSR/SSR/SSG 어느 방식과도 함께 사용할 수 있다.
특히 오프라인 기록 → 연결 시 동기화가 필요한 서비스(현장 기록, 구급일지 등)에 유용하다.
| 방식 | 생성 시점 | 서버 필요 | 속도 | SEO | 데이터 최신성 | 대표 사용 |
|---|---|---|---|---|---|---|
| CSR | 브라우저 실행 시 | ❌ | 느림 | 약함 | 실시간 | 내부 대시보드 |
| SSR | 요청 시 | ✅ | 빠름 | 강함 | 실시간 | 검색, 상품 |
| SSG | 빌드 시 | ❌ | 매우 빠름 | 강함 | 고정 | 블로그, 소개 |
| ISR | 빌드 + 주기적 재생성 | ⚙️ | 빠름 | 강함 | 주기적 최신 | 뉴스, 리스트 |
| 방식 | 실제 사용 비율 | 대표 서비스 |
|---|---|---|
| CSR | 약 40% | 관리자, 내부 시스템 |
| SSR | 약 30% | 커머스, 포털, 검색 서비스 |
| SSG | 약 15% | 기업 블로그, 문서 |
| ISR | 약 10% | 뉴스·상품 리스트 |
| PWA | 약 5% | 모바일·오프라인 현장 서비스 |
모던 프론트엔드에서는 한 가지 렌더링 방식만 쓰지 않는다.
서비스의 성격(로그인, 검색, 콘텐츠, 속도, 트래픽)에 따라
CSR + SSR + ISR + PWA를 조합해 최적의 사용자 경험과 서버 효율을 만든다.
이번 글에서는 그 조합의 원리와 실제 사용 패턴을 정리한다.
각 방식은 장단점이 분명하다.
| 방식 | 강점 | 약점 |
|---|---|---|
| CSR | 빠른 상호작용, 서버 부담 없음 | 초기 로딩 느림, SEO 약함 |
| SSR | 첫화면 빠름, SEO 강함 | 서버 부하 큼 |
| SSG/ISR | 빠르고 저비용 | 데이터 최신성 한계 |
| PWA | 오프라인, 설치형 UX | 브라우저 제약 |
서비스 전체를 하나로 고정하면 일부 화면은 과잉 설계가 된다.
예를 들어,
그래서 Next.js 같은 프레임워크는 “페이지별 렌더링 전략”을 지원한다.
Next.js에서는 페이지마다 서로 다른 렌더링 방식을 설정할 수 있다.
다음은 실제 실무형 구조 예시다.
/pages
├─ index.tsx → ISR (홈, 공지, 이벤트)
├─ product/[id].tsx → SSR (상품 상세)
├─ dashboard/index.tsx → CSR (로그인 사용자 대시보드)
└─ offline.tsx → PWA 오프라인 페이지
export async function getStaticProps() {
const data = await fetch(...);
return { props: { data }, revalidate: 300 }; // 5분마다 갱신
}
export async function getServerSideProps() {
const res = await fetch(...);
return { props: { product: await res.json() } };
}
function Dashboard() {
const { data } = useSWR('/api/me');
return <div>{data?.name}님 환영합니다</div>;
}
next-pwa 라이브러리로 Service Worker 등록.NetworkFirst, JS/CSS는 StaleWhileRevalidate.// next.config.js
const withPWA = require('next-pwa')({
dest: 'public',
register: true,
skipWaiting: true,
});
module.exports = withPWA({});
| 서비스 유형 | 렌더링 조합 | 이유 |
|---|---|---|
| 기업 랜딩/소개 | ISR | 트래픽 많고 업데이트 간헐적 |
| 상품 리스트 | ISR + CSR | 빠른 응답 + 즉시 필터링 |
| 검색결과 | SSR | SEO, 정확한 실시간 데이터 |
| 로그인 후 내부 페이지 | CSR | 비공개, 상호작용 위주 |
| 오프라인 기능 (모바일) | PWA | 연결 끊겨도 사용 가능 |
| 구분 | 적합한 렌더링 | 이유 |
|---|---|---|
| 초기 진입 속도 | SSR/ISR | 즉시 렌더링된 HTML 제공 |
| 빈번한 사용자 입력/대시보드 | CSR | 잦은 API 호출에 유리 |
| 정적 콘텐츠 | SSG/ISR | 캐싱 효율 극대화 |
| 오프라인·설치형 | PWA | 연결 의존도 제거 |
요약하면,
“보여주는 속도는 서버가,
상호작용은 브라우저가 담당한다.”
| 계층 | 기술 | 역할 |
|---|---|---|
| CDN | CloudFront / Vercel Edge | SSG/ISR 캐싱 |
| Web Server | Next.js (Node) | SSR 처리 |
| API Server | Spring / Express | 비즈니스 로직 |
| Storage | S3 / Redis | 정적 자산, 캐시 |
| Offline | PWA Service Worker | 오프라인 캐싱 |
Vercel이나 Netlify는 SSR·ISR·SSG를 동시에 처리하는 인프라를 자동 제공한다.
클라우드 없이 직접 운영할 경우,
| 방식 조합 | 사용 비율(체감) | 주요 사용처 |
|---|---|---|
| CSR 단독 | 약 40% | 내부용 시스템, 관리자 페이지 |
| SSR + CSR 혼합 | 약 30% | 쇼핑몰, 검색, 로그인 기반 서비스 |
| ISR + CSR 혼합 | 약 20% | 콘텐츠, 커머스 메인, 뉴스 |
| PWA 추가 조합 | 약 10% | 모바일, 오프라인 환경 서비스 |