SSR vs CSR
개요
1990년대부터 현재까지의 렌더링 방식 변천사를 큰 흐름으로 훑고, SSR/CSR의 명확한 비교와 함께 SSG, Universal Rendering까지 한 번에 이해하도록 돕는 글입니다.
1) 1990년대 → 2000년대 초: MPA 중심, 전통적 SSR의 시대
MPA(Multi-Page Application)의 특징
각 URL 요청마다 서버가 새로운 HTML 문서를 만들어 응답하는 방식입니다. 대부분의 동적 웹은 JSP, PHP, ASP 같은 서버 템플릿을 통해 렌더링했으며, 이것이 바로 전통적 SSR의 기본 형태였습니다.
전통적 SSR의 렌더링 방식
서버에서 완성된 HTML을 생성해 클라이언트에 전송하면, 브라우저는 이를 그대로 렌더링합니다. JavaScript가 포함될 수 있지만 하이드레이션(Hydration)은 없습니다.
초반에는 단순 DOM 조작 수준이었으나, 2000년대 후반에는 jQuery와 Ajax를 통해 상당히 복잡한 UI도 가능해졌습니다. 다만 렌더링 책임과 상태 관리는 여전히 서버 중심이었습니다.
장점과 한계
장점
- 첫 화면이 빠름
- 검색엔진 친화적
- 접근성과 링크 공유가 쉬움
한계
- 페이지 전환마다 전체 문서를 새로 고침해야 함
- 인터랙션이 끊김
- 클라이언트 UI 경험이 제한적
2) 2010년대 초중반: AJAX, SPA, CSR의 부상
SPA의 등장 배경
AJAX와 브라우저 성능 향상으로 클라이언트에서 상태를 관리하며 페이지를 조립하는 SPA(Single-Page Application)가 대중화되었습니다.
주요 프레임워크와 CSR 패턴
Angular, React, Vue 같은 프레임워크가 등장하면서 라우팅과 상태 관리, 데이터 페칭을 클라이언트가 담당하는 CSR 패턴이 보편화되었습니다.
장점과 한계
장점
- 부드러운 화면 전환
- 앱 같은 리치한 사용자 경험
- 오프라인 지원 및 동적 UI 구현 가능
한계
- 초기 로딩 번들 크기가 커질 경우 첫 화면 지연 발생
- SEO 대응이 초기에는 까다로움 (당시 많은 크롤러가 JS 실행을 지원하지 않았음)
3) 2010년대 후반 → 현재: 하이브리드의 시대 (SSR 재부상, SSG, Universal Rendering)
SSR 재부상
초기 페인트 속도를 확보하고 SEO 문제를 해결하려는 요구가 증가하면서 Next.js, Nuxt 등 프레임워크가 보편화되었습니다.
SSG(Static Site Generation)
빌드 타임에 HTML을 생성하여 CDN에 배포하는 방식입니다.
주요 특징
- 블로그/문서/마케팅 사이트에 이상적
- 트래픽 급증에도 안정적이고 저비용으로 운영 가능
- 정적 파일이므로 캐싱 효율이 극대화됨
Universal Rendering(Isomorphic Rendering)
기본 개념
- 동일한 애플리케이션 코드를 서버와 클라이언트에서 모두 실행할 수 있는 모델
- 개발자가 "서버 코드/클라이언트 코드"를 구분하지 않아도 같은 컴포넌트가 두 환경에서 동작하는 것이 목표
현대적 SSR 프레임워크의 실제 구현
현대적 SSR 프레임워크(Next.js, Nuxt.js)는 Universal Rendering 아이디어를 기반으로 하지만, 실제로는 서버와 클라이언트 컴포넌트를 명확히 구분합니다.
- 서버: 초기 HTML을 생성하여 빠른 로딩과 SEO 제공
- 클라이언트: Hydration을 통해 인터랙션 활성화
서버에서 생성된 HTML과 클라이언트의 가상 DOM을 동기화하는 과정입니다.
이론과 실제의 차이점
Next.js 13 이후는 use client
등으로 클라이언트 전용 컴포넌트를 명시해야 합니다. 따라서 현대적 SSR = Universal Rendering으로 단순히 동일시하기보다는 다음과 같이 구분하는 것이 정확합니다.
- Universal Rendering: 이론적 개념 (동일 코드 양쪽 실행)
- 현대적 SSR: 실현 가능한 형태로 각 환경별 코드를 구분하고 하이드레이션으로 연결하는 모델
SSG와 Universal Rendering은 언제 유리할까?
SSG(Static Site Generation)가 유리한 경우
- 콘텐츠가 자주 변하지 않고 읽기 위주일 때 최적입니다 (블로그/문서/마케팅 사이트)
- CDN 캐싱 덕분에 전 세계 어디서나 빠르고 저렴하게 서비스 가능합니다
- 변경이 잦다면 **ISR(증분 정적 재생성)**과 같은 전략을 활용할 수 있습니다
Universal Rendering이 유리한 경우
- 동일 코드를 서버에서 초기 렌더링 후 클라이언트에서 Hydration 가능합니다
- 라우트나 컴포넌트별로 SSR/CSR/SSG를 혼합하는 하이브리드 운영이 가능합니다
- 복잡한 앱에서 SEO, 성능, 개발 생산성의 균형을 잡는 현실적인 선택지입니다
전통적 SSR vs 현대적 SSR
많은 개발자가 혼동하는 부분을 명확히 구분해보겠습니다.
구분 | 전통적 SSR (JSP, PHP 등) | 현대적 SSR (Like Universal Rendering) |
---|---|---|
렌더링 주체 | 서버에서 HTML 생성 | 서버에서 초기 HTML 생성 + 클라이언트에서 하이드레이션 |
JavaScript 역할 | DOM 조작, Ajax 요청 | React/Vue 등 프레임워크의 상태 관리와 라우팅 |
하이드레이션 | 없음 | 있음 |
페이지 전환 | 전체 새로고침 | 클라이언트 사이드 라우팅 |
상태 관리 | 세션/쿠키/URL 파라미터 | 클라이언트 상태 + 서버 상태 동기화 |
인터랙션 | 제한적 | SPA 수준의 리치한 인터랙션 |
전통적 SSR은 서버 HTML 전송으로 끝나지만, Universal Rendering은 Hydration 과정을 거쳐 클라이언트에서 상태와 이벤트까지 활성화됩니다.
CSR vs 전통적 SSR vs 현대적 SSR 비교
항목 | CSR | 전통적 SSR | 현대적 SSR (Universal) |
---|---|---|---|
첫 화면 표시 속도 | 번들 실행 후 표시 → 느릴 수 있음 | 빠름(HTML 즉시 표시) | 빠름(HTML 즉시 표시) |
SEO | 별도 프리렌더링 필요 (현재는 충분히 대응 가능) | 매우 유리 | 매우 유리 |
하이드레이션 | 없음 | 없음 | 있음 |
페이지 전환 | 부드러운 클라이언트 라우팅 | 전체 새로고침 (끊김) | 부드러운 클라이언트 라우팅 |
서버 비용 | 낮음 (API/정적 파일만 제공) | 높을 수 있음(요청마다 서버 렌더링 필요) | 높음 (SSR + Hydration 복잡도) |
클라이언트 부담 | 높음 (전체 렌더링 책임) | 낮음 (HTML만 표시) | 중간 (Hydration 비용 발생) |
개발 복잡성 | 중간 (클라이언트 중심) | 낮음 (전통적 패턴) | 높음 (서버/클라이언트 경계 설계 필요) |
상호작용 응답성 | 높음 (최적화 필요) | 낮음 (새로고침 의존) | 높음 (Hydration 후 SPA 수준) |
현대적 SSR 프레임워크(예: Next.js, Nuxt.js)는 Hydration 과정에서 서버와 클라이언트의 렌더링 결과가 다르면 Hydration mismatch 오류가 발생할 수 있습니다.