2025-09-22 23:36

  • 서버사이드 렌더링(SSR)은 서버에서 완전한 HTML 페이지를 만들어 사용자에게 전달하는 렌더링 방식.
  • 클라이언트사이드 렌더링(CSR)의 느린 초기 로딩과 검색 엔진 최적화(SEO) 문제를 해결하기 위해 등장.
  • SSR은 빠른 초기 페이지 로딩(FCP)과 SEO에 강력하지만, 하이드레이션, 스트리밍 등 함께 이해해야 할 개념이 존재.

SSR 완벽 정복 핸드북 서버사이드 렌더링의 모든 것

오늘날 웹 애플리케이션은 그 어느 때보다 복잡하고 동적이다. 사용자는 데스크톱 앱과 같은 풍부한 상호작용을 기대하며, 개발자들은 이를 만족시키기 위해 React, Vue, Angular와 같은 강력한 자바스크립트 프레임워크를 사용한다. 이러한 프레임워크의 등장은 **클라이언트사이드 렌더링(Client-Side Rendering, CSR)**이라는 패러다임을 주류로 만들었다. 하지만 빛이 있으면 그림자가 있듯, CSR은 초기 로딩 속도 저하와 검색 엔진 최적화(SEO)라는 치명적인 약점을 드러냈다.

이 문제를 해결하기 위한 고민의 결과, 우리는 과거의 기술에서 새로운 해법을 찾았다. 바로 **서버사이드 렌더링(Server-Side Rendering, SSR)**이다. SSR은 최신 프레임워크의 장점과 전통적인 서버 렌더링의 장점을 결합한 현대적인 웹 개발의 핵심 기술로 자리 잡았다.

이 핸드북은 SSR이 왜 만들어졌는지, 어떤 구조로 동작하는지, 그리고 어떻게 사용하는지에 대한 모든 것을 깊이 있게 다룬다. CSR과의 비교부터 시작해 SSG, ISR과 같은 최신 렌더링 전략까지, SSR의 세계를 완벽하게 정복해 보자.


1. 만들어진 이유 모든 것은 SPA와 CSR로부터 시작되었다

SSR을 이해하려면 먼저 그 반대편에 있는 CSR이 무엇인지, 그리고 왜 그것만으로는 부족했는지를 알아야 한다.

싱글 페이지 애플리케이션(SPA)의 등장

과거의 웹사이트는 사용자가 링크를 클릭할 때마다 서버로부터 새로운 HTML 파일을 통째로 받아와 페이지 전체를 새로고침하는 방식이었다. 이를 **멀티 페이지 애플리케이션(Multi-Page Application, MPA)**이라 한다. 이 방식은 페이지 전환 시 깜빡임이 발생하고, 매번 전체 페이지를 다시 로드해야 해 사용자 경험이 매끄럽지 못했다.

이러한 단점을 극복하기 위해 **싱글 페이지 애플리케이션(Single Page Application, SPA)**이 등장했다. SPA는 최초에 단 하나의 HTML 페이지만 불러오고, 이후의 모든 페이지 전환이나 데이터 변경은 자바스크립트를 통해 동적으로 처리한다. 서버와는 필요한 데이터(주로 JSON 형식)만 주고받으며, 페이지 전체를 새로고침하는 대신 필요한 부분만 업데이트한다. 이로써 사용자들은 훨씬 빠르고 부드러운, 마치 데스크톱 앱과 같은 경험을 할 수 있게 되었다.

이 SPA를 구현하는 핵심 기술이 바로 **클라이언트사이드 렌더링(CSR)**이다.

클라이언트사이드 렌더링(CSR)의 명과 암

CSR은 말 그대로 렌더링의 주체가 **클라이언트(사용자의 브라우저)**라는 의미다.

CSR의 동작 방식:

  1. 사용자 요청: 사용자가 웹사이트 주소를 입력하면 브라우저는 서버에 접속한다.
  2. 서버 응답: 서버는 거의 비어있는 HTML 파일과 방대한 양의 자바스크립트(JS) 파일을 보낸다. 이 HTML 파일에는 <div id="root"></div>와 같은 뼈대만 존재한다.
  3. 브라우저 처리:
    • 브라우저는 이 텅 빈 HTML을 먼저 보여준다. (이때 사용자는 흰 화면을 보게 된다.)
    • 함께 받은 JS 파일을 다운로드하고 실행(parsing, executing)한다.
    • JS 코드가 실행되면서 API 서버에 데이터를 요청한다.
    • 데이터를 받은 후, JS가 동적으로 HTML 요소를 생성하여 비어있던 <div> 내부에 채워 넣는다.
  4. 렌더링 완료: 모든 컨텐츠가 화면에 그려지고, 사용자는 비로소 페이지를 볼 수 있으며 상호작용이 가능해진다.

이 방식은 초기 로딩만 끝나면 페이지 간 이동이 매우 빠르다는 장점이 있다. 하지만 두 가지 큰 문제점을 안고 있었다.

1. 느린 초기 로딩 속도 (Time To Content, TTP/FCP)

사용자가 처음 페이지에 접속했을 때, 컨텐츠를 보기까지의 과정이 너무 길다. 거대한 자바스크립트 번들을 다운로드하고, 실행하고, 다시 API 통신을 거쳐 화면을 그리는 동안 사용자는 **빈 화면(Blank Screen)**을 마주해야 한다. 이는 특히 인터넷 속도가 느리거나 저사양 기기에서 치명적인 사용자 경험 저하를 유발한다.

2. 검색 엔진 최적화(SEO)의 어려움

구글과 같은 검색 엔진은 웹사이트의 컨텐츠를 수집(crawling)하고 분석(indexing)하여 검색 결과에 노출한다. 그런데 CSR 방식에서는 검색 엔진 크롤러가 처음 받는 HTML이 텅 비어있다. 물론 구글봇은 이제 자바스크립트를 실행할 수 있지만, 여전히 완벽하지 않으며 모든 검색 엔진이 그런 것도 아니다. 또한, JS 실행에 실패하거나 시간이 오래 걸릴 경우 컨텐츠가 제대로 수집되지 않아 검색 결과에서 누락될 위험이 크다.

이러한 문제를 해결하기 위해 등장한 것이 바로 서버사이드 렌더링(SSR)이다. SSR은 SPA의 부드러운 사용자 경험은 유지하면서, CSR의 초기 로딩 및 SEO 문제를 해결하는 것을 목표로 한다.


2. 구조 SSR은 어떻게 동작하는가

SSR은 렌더링의 주체를 클라이언트에서 다시 서버로 가져온다. 마치 가구 조립에 비유할 수 있다.

  • CSR: 이케아 가구 세트를 배송받는 것과 같다. 고객(클라이언트)은 부품(JS, 데이터)을 모두 받은 뒤, 직접 설명서(JS 로직)를 보고 조립(렌더링)해야 완성된 가구를 볼 수 있다.
  • SSR: 완성된 가구를 배송받는 것과 같다. 공장(서버)에서 가구를 완벽하게 조립(렌더링)해서 고객(클라이언트)에게 보내준다. 고객은 받자마자 바로 사용할 수 있다.

SSR의 상세 워크플로우

  1. 사용자 요청: 브라우저가 특정 페이지(예: /products/123)를 서버에 요청한다.
  2. 서버 처리: 서버(주로 Node.js 환경)는 요청을 받고, 해당 페이지에 필요한 데이터를 파악한다.
  3. 데이터 페칭(Data Fetching): 서버는 데이터베이스나 외부 API에 필요한 데이터를 요청하여 가져온다. 예를 들어, 123번 상품의 이름, 가격, 이미지 등의 정보를 가져온다.
  4. HTML 생성: 서버는 가져온 데이터를 React나 Vue 같은 프레임워크의 컴포넌트에 주입하여 렌더링을 실행한다. 이 과정은 브라우저가 아닌 서버 환경에서 일어나며, 그 결과로 완성된 HTML 문자열이 생성된다. 이 HTML에는 모든 컨텐츠가 포함되어 있다.
  5. 서버 응답: 서버는 이렇게 생성된 완전한 HTML 파일을 자바스크립트 파일과 함께 클라이언트(브라우저)에 응답으로 보낸다.
  6. 브라우저 렌더링: 브라우저는 서버로부터 받은 HTML을 즉시 화면에 그린다. 사용자는 JS 파일이 다운로드되기 전에도 페이지의 모든 컨텐츠를 볼 수 있다. 초기 로딩 속도가 매우 빠르다.
  7. 하이드레이션 (Hydration): 페이지가 그려진 후, 백그라운드에서 다운로드된 자바스크립트 파일이 실행된다. 이 JS는 이미 존재하는 HTML 구조 위에 마치 물을 채우듯 이벤트 리스너를 추가하고, 페이지를 동적으로 상호작용할 수 있는 SPA로 전환시킨다. 이 과정을 하이드레이션이라고 한다.

하이드레이션이 완료되면, 사용자는 SSR의 빠른 초기 로딩과 CSR의 풍부한 상호작용 경험을 모두 누릴 수 있게 된다. 첫 페이지 진입은 SSR로, 그 이후의 페이지 이동은 CSR 방식으로 동작하여 두 마리 토끼를 모두 잡는 것이다.


3. 사용법 SSR vs CSR, 언제 무엇을 선택해야 할까

SSR과 CSR은 각각 뚜렷한 장단점을 가지고 있어, 프로젝트의 성격에 따라 적절한 기술을 선택하는 것이 중요하다.

특징서버사이드 렌더링 (SSR)클라이언트사이드 렌더링 (CSR)
렌더링 주체서버 (Server)클라이언트 (Client/Browser)
초기 로딩 속도빠름. 완성된 HTML을 바로 보여줌 (빠른 FCP)느림. JS 다운로드 및 실행 후 렌더링 (느린 FCP)
SEO매우 우수. 크롤러가 완전한 컨텐츠 수집 가능불리. JS 실행 능력에 따라 수집 여부 결정
서버 부하높음. 모든 사용자 요청마다 렌더링 수행낮음. 정적 파일 서빙 및 API 역할만 수행
페이지 이동초기에는 페이지 리로드 발생 (프레임워크가 CSR로 전환)매우 빠름. 필요한 부분만 동적으로 교체
개발 복잡도높음. 서버 환경 구성 및 데이터 처리 로직 필요상대적으로 낮음. 프론트엔드 개발에만 집중 가능
주요 사용 사례뉴스, 블로그, 이커머스 등 SEO와 첫 페이지 로딩이 중요한 서비스관리자 대시보드, 내부 툴 등 SEO가 불필요하고 상호작용이 많은 서비스

어떤 상황에 SSR을 선택해야 할까?

  • 검색 엔진 노출이 매우 중요할 때: 블로그, 뉴스 기사, 온라인 쇼핑몰 상품 페이지 등 컨텐츠 자체가 비즈니스의 핵심인 경우.
  • 첫 페이지 로딩 속도가 중요할 때: 사용자의 이탈률을 줄이고 좋은 첫인상을 주어야 하는 모든 서비스. 특히 모바일 사용자가 많은 경우 효과적.
  • 정적인 컨텐츠가 많은 페이지: 회사의 소개 페이지나 캠페인 랜딩 페이지처럼 내용이 자주 바뀌지 않으면서도 빠르게 보여줘야 할 때.

어떤 상황에 CSR을 선택해야 할까?

  • 로그인 후 사용하는 서비스: 관리자 페이지, 대시보드, 웹 기반 편집 툴(예: Figma, Google Docs) 등 SEO가 필요 없고, 한번 접속하면 오랜 시간 머무르며 복잡한 상호작용을 하는 경우.
  • 빠른 프로토타이핑이 필요할 때: 서버 환경 구성 없이 프론트엔드 개발에만 집중하여 빠르게 결과물을 만들어야 할 때.

4. 심화 내용 SSR을 넘어 진화하는 렌더링 전략

SSR은 웹 렌더링의 종착역이 아니다. 개발자들은 SSR의 단점(서버 부하, 느린 TTFB)을 보완하고 장점을 극대화하기 위해 새로운 렌더링 전략들을 만들어냈다.

1. 정적 사이트 생성 (Static Site Generation, SSG)

  • 개념: SSR이 **요청 시(request time)**에 페이지를 렌더링하는 것과 달리, SSG는 **빌드 시(build time)**에 모든 페이지를 미리 렌더링하여 HTML 파일로 만들어둔다.
  • 동작 방식: 개발이 끝나고 npm run build와 같은 명령어를 실행하면, 가능한 모든 경로의 페이지들을 미리 생성해둔다. 서버는 사용자의 요청이 오면, 이미 만들어진 HTML 파일을 그냥 전달만 해준다.
  • 장점: 렌더링 과정이 없으므로 속도가 비교 불가능할 정도로 빠르다. 서버 부하가 거의 없고, CDN(Content Delivery Network)을 통해 전 세계 어디서든 빠르게 컨텐츠를 제공할 수 있다.
  • 단점: 컨텐츠가 바뀌면 전체 사이트를 다시 빌드해야 한다. 동적인 데이터나 사용자별로 다른 컨텐츠를 보여주기 어렵다.
  • 사용 사례: 블로그, 기술 문서 사이트, 마케팅 페이지 등 내용 변경이 잦지 않은 사이트.

2. 점진적 정적 재생성 (Incremental Static Regeneration, ISR)

  • 개념: SSG의 ‘한번 빌드하면 바뀌지 않음’이라는 단점을 보완한 하이브리드 전략. Next.js에서 처음 도입했다.
  • 동작 방식: 기본적으로 SSG처럼 빌드 시점에 페이지를 생성한다. 하지만 특정 시간(예: 60초)이 지난 후 첫 사용자의 요청이 들어오면, 일단 기존의 정적 페이지를 보여주고 백그라운드에서 페이지를 새로 생성하여 다음 요청부터는 최신 페이지를 보여준다.
  • 장점: SSG의 압도적인 속도를 누리면서도 주기적으로 컨텐츠를 최신 상태로 업데이트할 수 있다.
  • 단점: 데이터가 실시간으로 반영되지는 않는다.
  • 사용 사례: 뉴스 사이트, 커뮤니티 게시판 등 준-실시간으로 컨텐츠 업데이트가 필요하지만, 모든 요청마다 렌더링할 필요는 없는 경우.

3. 스트리밍 SSR (Streaming SSR)

  • 개념: 전통적인 SSR의 단점을 개선한 최신 기술. React 18과 같은 라이브러리에서 지원한다.
  • 문제점: 기존 SSR은 서버에서 페이지 전체의 데이터 페칭과 렌더링이 끝나야만 클라이언트에게 응답을 보낼 수 있었다. 만약 특정 API 하나가 느려지면, 전체 페이지 로딩이 지연되는 병목 현상이 발생한다.
  • 해결책: 스트리밍 SSR은 서버에서 렌더링이 완료된 부분부터 점진적으로(stream) 클라이언트에 보낸다. 예를 들어, 페이지의 상단 레이아웃(헤더, 내비게이션 바)을 먼저 보내 브라우저가 그리게 하고, 데이터 로딩이 오래 걸리는 컨텐츠 영역은 로딩 스켈레톤을 보여준다. 이후 데이터 준비가 완료되면 해당 부분의 HTML을 추가로 보내 채워 넣는다.
  • 장점: TTFB(Time To First Byte)를 획기적으로 개선하여 사용자의 체감 로딩 속도를 높인다.
  • 사용 사례: 여러 개의 독립적인 컴포넌트가 각기 다른 API에서 데이터를 가져오는 복잡한 대시보드나 소셜 미디어 피드.

SSR을 지원하는 주요 프레임워크

이러한 복잡한 렌더링 전략을 밑바닥부터 구현하는 것은 매우 어렵다. 다행히도 우리에게는 훌륭한 프레임워크들이 있다.

  • Next.js (React 기반): SSR, SSG, ISR, 스트리밍 SSR 등 모든 현대적인 렌더링 전략을 지원하는 가장 강력하고 인기 있는 프레임워크.
  • Nuxt.js (Vue 기반): Vue 생태계의 Next.js. Vue 개발자들에게 SSR 환경을 손쉽게 구축할 수 있도록 지원한다.
  • SvelteKit (Svelte 기반): Svelte를 위한 공식 프레임워크로, 가볍고 빠른 성능을 자랑하며 다양한 렌더링 옵션을 제공한다.
  • Remix (React 기반): 웹 표준을 중시하며, 데이터 로딩과 라우팅에 강점을 가진 SSR 프레임워크.

결론 렌더링 전략, 정답은 없다

웹 개발의 세계에서 ‘은 탄환’은 없다. SSR, CSR, SSG, ISR은 각각의 트레이드오프를 가진 도구일 뿐이다.

  • CSR은 여전히 내부 관리자 페이지와 같이 고도의 상호작용이 필요한 비공개 애플리케이션에서 강력한 힘을 발휘한다.
  • SSR은 검색 엔진과 사용자 모두에게 빠른 첫인상을 주어야 하는 컨텐츠 중심의 서비스에 필수적이다.
  • SSGISR은 성능을 극한으로 끌어올리면서도 컨텐츠의 신선함을 유지하는 스마트한 대안을 제시한다.

현대적인 웹 프레임워크의 발전 덕분에 우리는 이제 페이지별로 다른 렌더링 전략을 조합하는 것도 가능하다. 예를 들어, 블로그의 글 목록은 ISR로, 글 상세 페이지는 SSG로, 사용자 프로필 페이지는 SSR로, 그리고 글쓰기 에디터는 CSR로 구현할 수 있다.

중요한 것은 우리가 만들고자 하는 서비스의 특성과 사용자의 기대를 정확히 이해하고, 그에 가장 적합한 렌더링 전략을 선택하는 것이다. 이 핸드북이 당신의 프로젝트에 최적의 렌더링 아키텍처를 설계하는 데 든든한 가이드가 되기를 바란다.