서론
웹 개발이랑 면접에서 기술면접에서 CSR, SSR이라는 용어가 자꾸 나옴
React는 CSR이고, Next.js는 SSR도 지원한다고 함
처음엔 "둘 다 HTML인데 뭐가 달라?" 싶었지만, 찾아보니 장단점이 확실히 다름
그래서 CSR과 SSR이 정확히 뭐고, 언제 뭘 써야 하는지 정리해봄
본론
CSR (Client Side Rendering) 이해하기
CSR은 렌더링을 클라이언트(브라우저)에서 함
서버는 빈 HTML과 JavaScript만 보내고, 브라우저가 나머지 일을 함
CSR의 흐름
1. 유저가 웹사이트 접속
↓
2. 서버가 빈 HTML 파일 전송
<html>
<body>
<div id="root"></div>
</body>
</html>
↓
3. 브라우저가 JavaScript 다운로드 및 실행
↓
4. JavaScript가 DOM을 동적으로 생성
React.render(<App />, document.getElementById('root'))
↓
5. 완성된 페이지가 화면에 표시
CSR 코드 예시 (React)
// App.js
import { useState, useEffect } from 'react';
export default function App() {
const [posts, setPosts] = useState([]);
const [loading, setLoading] = useState(true);
useEffect(() => {
// 브라우저에서 데이터 조회
fetch('/api/posts')
.then(res => res.json())
.then(data => {
setPosts(data);
setLoading(false);
});
}, []);
if (loading) return <div>로딩 중...</div>;
return (
<div>
<h1>블로그 글 목록</h1>
{posts.map(post => (
<div key={post.id}>
<h2>{post.title}</h2>
<p>{post.content}</p>
</div>
))}
</div>
);
}
CSR의 장점
- 개발이 간단함 (React, Vue, Angular 등)
- 서버 부하가 적음 (서버는 데이터만 보냄)
- 페이지 간 이동이 빠름 (JavaScript로 DOM만 바꿈)
- 사용자 상호작용에 즉시 반응
CSR의 단점
- 초기 로딩이 느림 (JavaScript 다운로드 + 실행 필요)
- SEO가 좋지 않음 (처음에 빈 HTML이라서 검색 엔진이 내용을 못 봄)
- 큰 JavaScript 번들 크기
초기 로딩 시간 비교
CSR: 1초 → 2초 → 3초 → 4초(완성)
HTML JS 실행 렌더링
SSR: 1초(완성)
완성된 HTML
SSR (Server Side Rendering) 이해하기
SSR은 렌더링을 서버에서 함
서버가 완성된 HTML을 만들어서 브라우저에 보냄
SSR의 흐름
1. 유저가 웹사이트 접속
↓
2. 서버가 데이터 조회
↓
3. 서버가 React 컴포넌트를 HTML로 변환
(Node.js에서 React를 렌더링)
↓
4. 완성된 HTML을 브라우저에 전송
<html>
<body>
<h1>블로그 글 목록</h1>
<div>
<h2>첫 번째 글</h2>
<p>내용...</p>
</div>
...
</body>
</html>
↓
5. 브라우저가 화면 표시 (매우 빠름)
↓
6. 브라우저가 JavaScript 다운로드 및 실행
(hydration - 상호작용 가능하게 만듦)
SSR 코드 예시 (Next.js)
// pages/posts.js
export default function Posts({ posts }) {
return (
<div>
<h1>블로그 글 목록</h1>
{posts.map(post => (
<div key={post.id}>
<h2>{post.title}</h2>
<p>{post.content}</p>
</div>
))}
</div>
);
}
// 서버에서 실행
export async function getServerSideProps() {
// 서버에서 데이터 조회
const response = await fetch('http://localhost:3001/api/posts');
const posts = await response.json();
return {
props: {
posts
}
};
}
SSR의 장점
- 초기 로딩이 빠름 (완성된 HTML을 바로 받음)
- SEO가 좋음 (HTML에 모든 내용이 있음)
- 느린 네트워크나 약한 기기에서도 빨리 보임
- 검색 엔진이 콘텐츠를 쉽게 크롤링
SSR의 단점
- 서버 부하가 높음 (매 요청마다 렌더링)
- 개발이 복잡함 (Node.js 서버 필요)
- 페이지 간 이동이 느릴 수 있음 (매번 서버에 요청)
- 확장성 문제 (트래픽 증가 시 서버 자원 부족)
CSR vs SSR 직접 비교
| 항목 | CSR | SSR |
|---|---|---|
| 렌더링 위치 | 브라우저 | 서버 |
| 초기 로딩 속도 | 느림 (JS 다운로드 필요) | 빠름 (완성된 HTML) |
| SEO | 나쁨 | 좋음 |
| 서버 부하 | 적음 | 높음 |
| 개발 복잡도 | 낮음 | 높음 |
| 인터랙션 속도 | 빠름 (JS만 실행) | 느릴 수 있음 (재요청) |
| 필요한 서버 | 정적 호스팅 (GitHub Pages) | Node.js 서버 필요 |
| 사용 예시 | 대시보드, SNS | 블로그, 뉴스, 전자상거래 |
시각적으로 이해하기
CSR - 초기 로딩
시간 →
브라우저 |━━━ JS 다운로드 ━━━|━━━ 파싱 ━━━|━━━ 렌더링 ━━━|
| |
0초 5초 (완성)
사용자 입장: 흰 화면만 보여서 답답함
SSR - 초기 로딩
시간 →
서버 |━━ 데이터조회 ━━|━━ 렌더링 ━━|
| |
0초 1초 (완성된 HTML 전송)
사용자 입장: 바로 내용이 보임
함께 사용하면 좋은 경우 (하이브리드 접근)
사실 CSR과 SSR은 배타적이지 않음
둘을 섞어서 사용하면 더 좋은 경우가 많음
예시 1: 초기 로딩은 SSR, 이후는 CSR
// Next.js로 초기 페이지는 SSR
export async function getServerSideProps() {
const posts = await fetchPosts();
return { props: { posts } };
}
// 클라이언트에서는 상호작용은 CSR으로
export default function Posts({ posts }) {
const [filtered, setFiltered] = useState(posts);
const [search, setSearch] = useState('');
const handleSearch = (e) => {
const term = e.target.value;
setSearch(term);
// 브라우저에서 즉시 필터링 (SSR과 관계없이)
setFiltered(
posts.filter(p => p.title.includes(term))
);
};
return (
<div>
<input
placeholder="검색..."
onChange={handleSearch}
/>
{filtered.map(post => <Post key={post.id} post={post} />)}
</div>
);
}
흐름
- 사용자가 페이지 접속 → SSR로 빠르게 초기 콘텐츠 로드
- 사용자가 검색 입력 → CSR로 즉시 필터링 (서버 요청 없음)
예시 2: 중요한 콘텐츠는 SSR, 추가 콘텐츠는 CSR
export default function ProductPage({ product }) {
const [reviews, setReviews] = useState(null);
const [reviewsLoading, setReviewsLoading] = useState(false);
const loadReviews = async () => {
setReviewsLoading(true);
const data = await fetch(`/api/reviews/${product.id}`);
setReviews(await data.json());
setReviewsLoading(false);
};
return (
<div>
{/* SSR로 미리 받은 상품 정보 - 빠르게 보임 */}
<h1>{product.name}</h1>
<p>{product.description}</p>
<p>가격: {product.price}원</p>
{/* 리뷰는 필요할 때만 CSR로 로드 */}
<button onClick={loadReviews}>리뷰 보기</button>
{reviewsLoading && <div>로딩 중...</div>}
{reviews && reviews.map(r => <Review key={r.id} review={r} />)}
</div>
);
}
export async function getServerSideProps(context) {
const { id } = context.params;
const product = await fetchProduct(id);
return { props: { product } };
}
흐름:
- 페이지 접속 → SSR로 상품 정보 빠르게 로드 (SEO 좋음)
- "리뷰 보기" 클릭 → CSR로 필요할 때만 리뷰 로드
언제 뭘 써야 할까?
CSR을 쓰면 좋을 때
- 대시보드, 관리자 페이지 (SEO 안 필요)
- 내가 로그인한 개인 데이터 (미리 렌더링할 수 없음)
- 실시간으로 자주 업데이트되는 콘텐츠
- 사용자와의 상호작용이 많은 경우
- 정적 호스팅만 가능한 경우
SSR을 쓰면 좋을 때
- 블로그, 뉴스, 문서
- SEO가 중요한 경우
- 초기 로딩 속도가 중요한 경우
- 검색 엔진 크롤링이 필요한 경우
둘 다 같이 쓰는게 좋은 방법!
- 대부분의 현대적 웹앱 (Next.js, Nuxt 권장)
- 초기 로딩은 빠르게(SSR), 상호작용은 부드럽게(CSR)
결론
CSR은 브라우저에서 렌더링 → 개발 간단, 상호작용 빠름, 하지만 초기 로딩 느림
SSR은 서버에서 렌더링 → 초기 로딩 빠름, SEO 좋음, 하지만 서버 부하 높음
"뭐가 더 좋아?"라는 질문은 의미 없고, 상황에 맞게 선택하거나 섞어서 써야 함
요즘 트렌드는 SSR의 초기 로딩 속도 + CSR의 상호작용 부드러움을 모두 누리는 하이브리드 방식
Next.js, Nuxt, Remix 같은 풀스택 프레임워크가 이걸 지원하는 이유도 여기 있음
앞으로 웹앱 만들 때 상황에 맞게 CSR, SSR, 그리고 둘의 조합을 잘 활용해야겠음!
'프론트엔드 > Next.js' 카테고리의 다른 글
| (Next.js) 서버 컴포넌트 + 클라이언트 상태 관리 전략 (0) | 2025.11.12 |
|---|---|
| (Next.js) 주요 특징 SSR vs SSG (0) | 2025.05.12 |
| (Next.js) npm run dev와 npm start 차이 (4) | 2025.01.09 |
| (Next.js) PWA 구현 (4) | 2025.01.07 |