IT의 IT 블로그
웹 라우팅과 렌더링 방식 정리 (SPA·MPA, CSR·SSR·SSG·ISR) 본문
이번 글에서는
SPA·MPA라는 라우팅 전략과
CSR·SSR·SSG·ISR이라는 렌더링 전략이
어떤 기준으로 나뉘는 개념인지를 정리해보려 합니다.
특히
SPA = CSR, MPA = SSR처럼
관습적으로 묶여 설명되면서 헷갈렸던 개념들을
구조적으로 다시 분리해 이해하는 것이 목표입니다.
들어가며 — 왜 이 개념들이 헷갈릴까?
관련 글들을 보다 보면 흔히 다음과 같은 설명을 접합니다.
- SPA의 대표 사례 → React, Vue → 보통 CSR
- MPA의 대표 사례 → JSP, PHP → 보통 SSR
직관적으로는 맞는 말처럼 보이지만,
이 설명은 기준이 서로 다른 개념들을 한 줄로 묶어버린 것에 가깝습니다.
실제로는,
- JSP로도 SPA처럼 동작하는 구조를 만들 수 있고
- React 역시 실행 환경에 따라 CSR, SSR 모두 가능합니다
혼란의 원인은 대부분
라우팅 방식과 렌더링 방식을 구분하지 않고 이해하기 때문입니다.
그래서 본격적인 설명에 앞서,
같은 “페이지 이동”이 어떻게 다르게 구현되는지
간단한 코드로 먼저 살펴보겠습니다.
개념 이해를 위한 코드 비교
전통적인 MPA 방식 (JSP 예시)
<!-- list.jsp -->
<a href="/detail.jsp?id=1">상품 상세로 이동</a>
<!-- detail.jsp -->
<%
String id = request.getParameter("id");
%>
<h1>상품 상세 페이지</h1>
<p>상품 ID: <%= id %></p>
동작 방식
- 링크 클릭
- 브라우저가 서버에 새 HTML 요청
- 서버가 HTML을 생성해 응답
- 화면 전체가 교체됨
▶ URL 변경 = 새로운 HTML 요청 → MPA
MPA 기술로 “SPA처럼” 보이게 만드는 방식 (AJAX)
<!-- index.jsp -->
<button onclick="loadDetail(1)">상품 상세 보기</button>
<div id="app"></div>
<script>
function loadDetail(id) {
fetch(`/detail.jsp?id=${id}`)
.then(res => res.text())
.then(html => {
document.getElementById("app").innerHTML = html;
history.pushState(null, "", `/detail?id=${id}`);
});
}
</script>
동작 방식
- HTML은 최초 한 번만 로드
- 이후에는 부분 HTML만 받아서 교체
- URL은 변경되지만 새로고침 없음
▶ 기술은 JSP지만, 동작 방식은 SPA에 가깝다
전형적인 SPA 방식 (React)
import { BrowserRouter, Routes, Route, Link } from "react-router-dom";
function App() {
return (
<BrowserRouter>
<Link to="/detail/1">상품 상세</Link>
<Routes>
<Route path="/detail/:id" element={<Detail />} />
</Routes>
</BrowserRouter>
);
}
function Detail() {
return <h1>상품 상세 페이지</h1>;
}
동작 방식
- 최초 HTML + JS 로드
- 이후 페이지 이동은 클라이언트 라우터가 처리
- 서버는 데이터 제공 역할
▶ SPA = 클라이언트가 라우팅을 담당
이 코드들이 말해주는 핵심
- SPA / MPA는 프레임워크가 아니라 동작 방식
- 어떤 기술을 쓰느냐보다
페이지 이동을 누가 처리하느냐가 중요하다
이제 이 기준을 가지고 개념을 정리해보겠습니다.
1. SPA와 MPA — 라우팅 전략의 차이
1.1 라우팅이란?
라우팅(Routing)이란
URL 변경에 따라 어떤 화면을 보여줄지 결정하는 방식입니다.
즉,
페이지 이동을 서버가 처리하느냐, 클라이언트가 처리하느냐의 차이입니다.
1.2 MPA (Multi Page Application)
MPA는 전통적인 웹 애플리케이션 구조입니다.
특징
- URL 변경 시 브라우저가 서버에 요청
- 서버가 HTML을 생성
- 페이지 이동마다 전체 문서 교체
장점
- 구조가 직관적이고 단순함
- 페이지별 SEO 최적화가 용이
- 서버 중심 보안 및 권한 처리에 유리
단점
- 페이지 이동 시 UX가 끊길 수 있음
- 동일한 UI를 반복 로딩
- 상태 유지가 어려움
적합한 상황
- 전통적인 웹 서비스
- 관리자·공공기관 시스템
- SEO와 접근성이 중요한 페이지
1.3 SPA (Single Page Application)
SPA는 하나의 HTML 문서를 기준으로 동작합니다.
특징
- HTML 최초 1회 로드
- 이후 URL 변경은 클라이언트 처리
- 서버에 새 HTML 요청 없음
장점
- 빠른 페이지 전환
- 자연스러운 UX
- 복잡한 상태 관리에 유리
단점
- 초기 로딩 비용 증가
- SEO 대응을 별도로 고려해야 함
적합한 상황
- 사용자 인터랙션이 많은 서비스
- 대시보드, 웹앱, SaaS
1.4 정리 — 라우팅 전략 기준
| 구분 | MPA | SPA |
| 라우팅 주체 | 서버 | 클라이언트 |
| HTML 요청 | 페이지마다 | 최초 1회 |
| 페이지 전환 | 전체 교체 | 부분 갱신 |
2. CSR과 SSR — 렌더링 전략의 차이
SPA / MPA가 페이지 이동 방식이라면,
CSR / SSR은 HTML을 어디에서 생성하느냐에 대한 개념입니다.
2.1 CSR (Client Side Rendering)
CSR(Client Side Rendering)은 웹 브라우저에서 JavaScript를 사용하여 웹페이지를 렌더링 하는 방식입니다.
즉, 사용자의 브라우저가 서버로부터 데이터를 받아와서 웹 페이지를 직접 생성합니다.

동작 방식
1. 사용자가 웹 사이트에 요청을 보냅니다.
2. CDN이 HTML 파일과 JS로 접근 할 수 있는 링크를 클라이언트로 보냅니다.
3. 클라이언트는 HTML과 JS를 다운로드 받습니다.
4. 브라우저가 자바스크립트를 다운 받습니다.
5. 다운로드가 완료된 JS가 실행이 되며 데이터를 위한 API가 호출이 됩니다.
6. 서버가 API로 부터의 요청에 응답합니다.
7. API로부터 받아온 데이터를 placeholer 자리에 넣어줍니다. 이제 페이지가 상호작용이 가능해 집니다.
코드 예시
<!-- 서버가 내려주는 HTML -->
<div id="root"></div>
<script src="/app.js"></script>
// app.js
document.getElementById("root").innerHTML = "<h1>Hello</h1>";
CSR은 왜 SEO에 불리할까?
- 초기 HTML에 콘텐츠가 없음
- 검색 엔진은 HTML 기준으로 페이지를 수집
- JavaScript 실행이 필요한 페이지는
크롤링 지연 또는 누락 가능성 존재 - 렌더링 실패 시 콘텐츠 인식 불가
(최근 검색 엔진은 JS 렌더링을 지원하지만,
비용·타이밍·안정성 문제는 여전히 존재)
장점
- 인터랙션 성능 우수
- 서버 부하 적음
단점
- 초기 로딩 느림
- SEO 리스크 존재
적합한 상황
- 사용자와의 상호작용이 많은 웹사이트에 적합합니다.
- 어드민 페이지
- 로그인 기반 서비스
- 검색 노출이 중요하지 않은 앱
2.2 SSR (Server Side Rendering)
SSR(Server Side Rendering)은 서버에서 HTML을 완성하여 브라우저로 보내는 방식입니다.

동작 방식
1. 사용자가 웹 사이트에 요청을 보냅니다.
2. Server는 ‘Ready to Render’ 즉시 렌더링 가능한 html 파일을 만듭니다.
3. 클라이언트에 전달하는 순간 이미 렌더링 준비가 되었기 때문에 HTML이 즉시 렌더링이 됩니다.
하지만 사이트에서 조작은 불가능 합니다.(JavaScript가 읽히기 전입니다.)
4. 브라우저가 자바스크립트를 다운 받습니다.
5. 다운로드가 이루어 지고 있는 상태에서 사용자는 컨텐츠를 볼 수 있지만 사이트를 조작 할 수 는 없습니다.
이때 사용자의 조작을 기억하고 있습니다.
6. 브라우저가 JavaScript FrameWork를 실행합니다.
7. JS 까지 성공적으로 컴파일 되었기 때문에 아까 기억하고 있던 사용자의 조작이 실행이 되고 이제 웹 페이지는 상호작용이 가능해 집니다.
코드 예시
// 서버 코드 (개념 예시)
const html = renderToString(<App />);
res.send(`
<html>
<body>${html}</body>
</html>
`);
장점
- 빠른 초기 화면
- SEO에 유리
단점
- 서버 부하 증가
- 트래픽 증가 시 비용 상승
적합한 상황
- 동적 콘텐츠가 많은 웹사이트에 적합합니다.
- 사용자의 요청에 따라 콘텐츠가 실시간으로 변경되어야 하는 경우, 서버에서 렌더링을 통해 항상 최신 상태의 웹 페이지를 제공할 수 있습니다.
- 예를 들어, 사용자 맞춤형 콘텐츠를 제공하는 웹사이트, 주식 정보와 같이 실시간으로 변경되는 데이터를 다루는 웹사이트 등에서 사용할 수 있습니다.
- 콘텐츠 중심 서비스
- 검색 유입이 중요한 페이지
중요한 오해 정리
- React = CSR ❌
- React를 어디서 실행하느냐가 중요
| 실행 위치 | 렌더링 |
| 브라우저 | CSR |
| 서버 | SSR |
3. SPA인데 SSR이 가능한 이유
- SPA → 페이지 이동 방식
- SSR → HTML 생성 위치
즉,
- 최초 요청: 서버에서 HTML 생성 (SSR)
- 이후 이동: 클라이언트 라우팅 (SPA)
이 구조가 바로 Next.js의 기본 철학입니다.
서버에서 내려온 HTML에
클라이언트 JS가 이벤트를 연결하는 과정을
Hydration이라고 합니다.
4. SSG (Static Site Generation)

// 빌드 시
generateHTML("/blog/1");
SSG(Static Site Generation)는 빌드 시에 모든 페이지를 HTML로 미리 생성하는 방식입니다.
4.1. 동작 과정
- 빌드 시에 서버는 모든 가능한 요청에 대한 HTML을 미리 생성합니다.
- 사용자가 웹사이트에 접속하면, 서버는 미리 생성해 둔 HTML을 보냅니다.
- 브라우저는 받은 HTML을 표시합니다.
- 추가 페이지 요청 시, 미리 생성해 둔 해당 페이지의 HTML을 보냅니다.
장점
- 매우 빠른 로딩
- 서버 부하 최소화
- SEO 최상
단점
- 데이터 변경 시 재빌드 필요
적합한 상황
- 내용이 자주 변경되지 않은 웹사이트에 적합합니다.
- 블로그
- 포트폴리오
- 회사 소개 페이지
5. ISR (Incremental Static Regeneration)

export const revalidate = 60; // 60초
SSG와 SSR의 단점을 보완하고 장점을 결합한 Next.js 프레임워크에서 도입한 렌더링 방식입니다.
빌드 시점에 페이지를 미리 생성하면서도 특정 시간 간격으로 페이지를 재생성하여 업데이트된 데이터를 반영할 수 있게 합니다.
5.1. 동작 과정
- 빌드 시점: 빌드 시점에 웹 페이지를 정적으로 생성합니다.
이때, Next.js에서는 getStaticProps와 revalidate 옵션을 이용하여 페이지를 어떻게 생성하고, 언제 생성할지를 설정할 수 있습니다. - 사용자 접속 시: 웹 사이트에 접속하면 미리 생성된 HTML을 보냅니다.
- 페이지 표시: 브라우저는 받은 HTML을 표시합니다.
- 새로운 요청 및 페이지 재생성: 새로운 사용자의 요청이 들어왔을 때, revalidate 옵션에 설정된 시간이 경과하면, 해당 페이지를 서버에서 재생성합니다. 이때, 새로운 사용자는 이전 페이지를 보게 됩니다.
이유는 설정된 시간이 경과되어도 새로운 요청이 없으면 재생성하지 않기 때문입니다. 새로운 요청이 있을 때에만 페이지가 재생성되며, 재생성 중에는 이전의 페이지가 계속해서 보이게 됩니다.
장점
- SSG 속도 + 데이터 갱신 가능
- 서버 부하 낮음
단점
- 실시간 데이터에는 부적합
- 구조 이해 필요
적합한 상황
- 일부 페이지는 자주 업데이트되고, 다른 일부 페이지는 그렇지 않은 경우에 사용할 수 있습니다.
- 예를 들어, 쇼핑 사이트에서는 일부 상품 정보는 자주 업데이트 되지만, 회사 소개나 이용 약관 등의 페이지 등 그렇지 않은 경우를 뜻합니다.
- 상품 페이지
- 콘텐츠 플랫폼
6. 모든 조합은 가능하다
지금까지의 내용을 정리하면,
라우팅 전략(SPA / MPA)과 렌더링 전략(CSR / SSR / SSG / ISR)은
서로 다른 기준에서 결정되는 개념입니다.
그래서 실제 서비스에서는 다음과 같은 조합이 모두 가능합니다.
▸ MPA + CSR
- 페이지 이동은 서버가 담당 (MPA)
- 각 페이지 내부의 UI는 JavaScript로 렌더링 (CSR)
예를 들면,
- JSP, PHP 기반 MPA 구조
- 각 페이지에 React, Vue 위젯을 부분적으로 삽입
- 페이지 단위 SEO는 유지하면서,
특정 영역만 인터랙션 강화
이 조합은
기존 레거시 시스템을 유지하면서 점진적으로 프론트엔드를 고도화할 때
자주 사용됩니다.
▸ SPA + SSR
- 최초 페이지 요청 시 서버에서 HTML 생성 (SSR)
- 이후 페이지 이동은 클라이언트 라우터가 처리 (SPA)
이 구조가 바로
Next.js 기반 애플리케이션의 대표적인 형태입니다.
- 초기 화면은 빠르게 보여주고
- 이후에는 SPA처럼 부드러운 UX 제공
- SEO와 사용자 경험을 동시에 고려
콘텐츠와 인터랙션이 모두 중요한 서비스에서 많이 선택됩니다.
▸ SPA + SSG / ISR
- 라우팅은 SPA 방식
- HTML은 빌드 시(SSG) 또는 일정 주기(ISR)로 미리 생성
이 경우,
- 서버 부하는 최소화하면서
- 매우 빠른 응답 속도와 SEO를 확보
- 데이터 변경 빈도에 따라 SSG / ISR 선택
블로그, 마케팅 페이지, 상품 상세 페이지처럼
정적 성격이 강하지만 완전히 고정되지는 않은 서비스에 적합합니다.
결국 중요한 것은
이 조합들을 보면 알 수 있듯이,
- SPA냐 MPA냐
- CSR이냐 SSR이냐
는 서로를 결정하는 관계가 아닙니다.
중요한 것은
어떤 기술을 쓰느냐가 아니라,
어떤 “방식”으로 화면을 만들고 이동시키느냐입니다.
프레임워크 이름을 기준으로 외우기 시작하면
개념은 반드시 헷갈리게 됩니다.
반대로,
- 페이지 이동은 누가 처리하는가?
- HTML은 어디에서 생성되는가?
- SEO와 UX 중 무엇이 더 중요한가?
이 질문을 기준으로 생각하면
어떤 조합이든 자연스럽게 이해할 수 있습니다.
7. 렌더링 방식 비교 표
| 방식 | SEO | 초기 로딩 | 서버 부하 | 적합한 사례 |
| CSR | 낮음 | 느림 → 빠름 | 낮음 | 어드민 |
| SSR | 높음 | 빠름 | 보통 | 콘텐츠 |
| SSG | 높음 | 매우 빠름 | 매우 낮음 | 블로그 |
| ISR | 높음 | 빠름 | 낮음 | 상품 페이지 |
8. 최종 마무리
이 글에서 가장 중요한 결론은 하나입니다.
SPA냐 MPA냐,
CSR이냐 SSR이냐는 정답 문제가 아니라
“서비스 성격에 맞는 선택의 문제”다.
- UX가 중요한가?
- SEO가 중요한가?
- 서버 비용과 트래픽은 어떤가?
이 질문에 대한 답이
라우팅 전략과 렌더링 전략을 결정합니다.
React, Next.js는
어떤 방식을 강요하는 기술이 아니라
상황에 맞는 선택지를 제공하는 도구입니다.
다만,
그렇다고 해서 아무 방식이나 섞어 쓰는 것이 효율적이다는 의미는 아닙니다.
React는 기본적으로
- 컴포넌트 기반 UI
- 클라이언트 상태 중심의 화면 구성
- SPA 아키텍처에 최적화된 설계
라는 명확한 철학과 방향성을 가지고 만들어진 라이브러리입니다.
그래서 React를 사용한다면,
굳이 MPA 구조를 억지로 흉내 내거나
SPA의 장점을 포기하면서까지 다르게 사용할 필요는 없습니다.
마찬가지로 Next.js 역시
- 파일 기반 라우팅
- SSR / SSG / ISR의 자연스러운 선택
- 서버와 클라이언트 역할 분리
를 전제로 설계된 프레임워크이기 때문에,
이 철학을 따라가는 것이 가장 단순하고, 가장 안정적인 선택이 됩니다.
중요한 것은
“이 기술로 모든 방식을 다 구현할 수 있다”가 아니라,
이 기술이 의도한 사용 방식 안에서
어떤 전략을 선택하는지가 중요하다는 점입니다.
즉,
- React를 쓴다면 SPA 철학을 기반으로
- Next.js를 쓴다면 서버 렌더링 전략을 도구처럼 활용하고
- 그 위에서 CSR / SSR / SSG / ISR을 상황에 맞게 선택하면 됩니다.
결국 개념을 정리하는 이유는,
프레임워크를 다르게 쓰기 위해서가 아니라
원래 의도한 방식대로 쓰기 위해서입니다.
이상으로 정리를 마칩니다.
이 글이 개념을 정리하는 데 도움이 되었기를 바랍니다.
읽어주셔서 감사합니다.
'Frontend Basic (기초 이론)' 카테고리의 다른 글
| 번들러 동작 원리 이해하기 (0) | 2026.03.15 |
|---|---|
| CommonJS 와 ES Module 차이 이해하기 (0) | 2026.02.20 |
| 얕은 복사 / 깊은 복사 정리 (0) | 2026.02.09 |
| 브라우저 렌더링 과정과 엔진 구조 정리 (0) | 2026.01.06 |
| 자바스크립트 비동기 흐름 정리 (0) | 2025.12.08 |