5. IT기술노트/인프라&개발

SSR(Server Side Rendering): 왜, 어떻게, 그리고 언제 써야 할까?

쿼드큐브 2025. 10. 16. 19:40
반응형

반응형

 

SSR(Server Side Rendering): 왜, 어떻게, 그리고 언제 써야 할까?

SSR(Server Side Rendering) 삽화 이미지
SSR(Server Side Rendering) 삽화 이미지

 

1. SSR의 개념과 등장 배경

🔷 SSR이란 무엇일까?

SSR(Server Side Rendering)은 말 그대로 서버에서 페이지를 렌더링 하는 방식입니다.

사용자가 웹사이트를 요청하면, 서버는 필요한 데이터를 조회해 완성된 HTML 페이지를 직접 만들어 응답합니다.

 

이 HTML은 브라우저에서 즉시 렌더링되어 사용자에게 빠르게 화면을 보여주고, 이후 자바스크립트가 실행되면서 페이지가 상호작용 가능한 상태로 전환됩니다.
즉, SSR은 “보여줄 준비가 된 완성본”을 먼저 보내는 개념입니다.


반면 CSR(Client Side Rendering)은 클라이언트 중심의 방식입니다.
서버는 단순히 HTML 껍데기와 JS 번들만 전달하고, 실제 콘텐츠는 브라우저에서 자바스크립트가 실행되며 동적으로 채워집니다.
이 때문에 CSR은 첫 로딩 시 “빈 화면 → 로딩 스피너 → 완성된 페이지”의 흐름을 보이죠

구분 CSE SSR
초기 렌더링 위치 브라우저에서 수행 서버에서 수행
SEO(검색 노출) 불리함 (HTML이 비어 있음) 유리함 (완성된 HTML 제공)
초기 로딩 속도 느림 (JS 실행 후 렌더링) 빠름 (HTML 즉시 표시)
서버 부하 적음 많음

CSR은 한 번 로딩이 끝나면 이후 페이지 전환이 매우 빠르지만,

SSR은 첫 진입 시부터 완성된 콘텐츠를 볼 수 있다는 점에서 초기 경험(First Paint)이 훨씬 부드럽습니다.

 

🔷 왜 SSR이 다시 등장했을까?

한때 SPA(Single Page Application) 구조가 웹 개발의 주류가 되면서 CSR이 대세로 자리 잡았습니다.
React, Vue, Angular 같은 프레임워크들이 CSR 중심으로 발전했죠. 하지만 시간이 지나면서 CSR의 근본적인 한계가 드러났습니다.

 

1. 초기 로딩 지연

브라우저가 JS 번들을 모두 다운로드하고 실행해야만 화면이 만들어지기 때문에, 네트워크가 느리거나 디바이스 성능이 낮을수록 첫 화면이 늦게 뜹니다.

 

2. SEO 문제

검색 엔진은 HTML을 읽어야 콘텐츠를 인식하는데, CSR 페이지는 초기 HTML이 비어 있어 크롤러가 내용을 인식하지 못합니다.
특히 상품 상세, 블로그, 뉴스 페이지처럼 검색 유입이 중요한 페이지에서는 치명적이었습니다.

 

이런 한계를 해결하기 위해, “서버에서 미리 그려서 보내자”는 SSR 방식이 다시 주목받게 되었습니다.

현재 SSR을 지원하는 대표적인 프레임워크들은 다음과 같습니다.

🔸Next.js (React 기반)
🔸Nuxt.js (Vue 기반)
🔸SvelteKit
🔸Remix (React 기반 풀스택 프레임워크)

이들은 모두 “서버에서 HTML을 미리 그린 뒤, 클라이언트에서 하이드레이션(Hydration)으로 인터랙션을 복원하는 구조”를 갖습니다.

 

🔷 SSR의 작동 과정 한눈에 보기

SSR의 요청-응답 흐름은 아래처럼 요약할 수 있습니다.

1. 사용자가 특정 페이지를 요청함 (/posts/1)
2. 서버가 필요한 데이터를 DB나 API로부터 가져옴
3. 서버가 이 데이터를 기반으로 HTML을 생성
4. 완성된 HTML을 클라이언트로 전송

5. 브라우저는 HTML을 즉시 표시하고,
이후 자바스크립트가 실행되어 페이지를 “살아 있는” 상태로 만듦 (Hydration)

Hydration이란?
서버에서 미리 렌더링된 정적인 HTML에 브라우저의 자바스크립트 이벤트와 상태를 주입하여 동적인 SPA처럼 동작하게 만드는 과정입니다.
[사용자 요청]
       ↓
[서버] → 데이터 조회 → HTML 렌더링
       ↓
[완성된 HTML 전송]
       ↓
[브라우저 표시] → (JS 실행) → 하이드레이션 완료

 

2. SSR의 장점과 단점

SSR(Server Side Rendering)은 단순히 “서버에서 HTML을 만들어 보내는 기술”을 넘어서, 웹의 속도와 검색 노출, 사용자 경험(UX) 전반에 영향을 주는 중요한 렌더링 전략입니다.

하지만 모든 기술이 그렇듯, 장점이 있으면 반드시 단점도 존재합니다.

이번 섹션에서는 SSR의 강점과 한계, 그리고 언제 선택해야 하는지를 균형 있게 살펴보겠습니다.

 

🔷 SSR의 주요 장점

1. 빠른 초기 렌더링 (Fast First Paint)

SSR의 가장 큰 매력은 “화면이 빠르게 뜬다”는 점입니다.
서버에서 완성된 HTML을 전달하기 때문에, 브라우저는 별도의 자바스크립트 실행 없이도 즉시 페이지를 렌더링할 수 있습니다.

특히 저사양 기기나 느린 네트워크 환경에서는 체감 속도 차이가 극명하게 나타납니다.

 

예를 들어, CSR 기반 SPA에서는 첫 진입 시 흰 화면만 잠시 보이다가 JS 번들이 로드된 후 콘텐츠가 나타납니다.
하지만 SSR 페이지는 HTML이 이미 완성되어 있으므로, 사용자는 곧바로 콘텐츠를 확인할 수 있죠.

 

2. SEO(검색 엔진 최적화)에 유리

검색 엔진(구글, 네이버, 빙 등)은 웹페이지의 HTML 콘텐츠를 읽고 색인(indexing)합니다.
그런데 CSR은 HTML이 거의 비어 있고, 콘텐츠가 JS로 나중에 채워지기 때문에 검색 엔진이 페이지 내용을 제대로 인식하지 못하는 경우가 많습니다.

SSR은 서버에서 이미 HTML이 완성되어 내려오기 때문에, 검색 엔진이 쉽게 콘텐츠를 수집할 수 있습니다.
따라서 블로그, 뉴스, 쇼핑몰, 제품 상세 페이지처럼 검색 유입이 중요한 서비스에서는 SSR이 사실상 필수에 가깝습니다.

 

3. 소셜 미리보기(Open Graph)와 메타 태그 지원

페이스북, 카카오톡, 슬랙 등에서 링크를 공유하면 썸네일 이미지와 제목, 설명이 함께 표시되는 것을 본 적 있을 겁니다.
이 정보는 HTML의 메타 태그(meta tag)를 통해 생성되는데, CSR 환경에서는 이 메타 정보가 렌더링 전에 비어 있어 제대로 표시되지 않습니다.

SSR은 서버에서 페이지를 렌더링할 때 이미 메타 태그를 포함하므로 소셜 미리보기도 완벽하게 표시됩니다.
즉, SNS 공유에 최적화된 구조라고 볼 수 있죠.

 

🔷 SSR의 한계와 주의점

1. 서버 부하 증가

CSR은 한 번 빌드된 정적 파일만 제공하면 되지만, SSR은 요청마다 렌더링을 수행해야 합니다.
즉, 페이지 요청이 많을수록 서버 부하가 커지고, 트래픽 폭주 시 서버가 쉽게 병목에 걸릴 수 있습니다.

실무 팁:
SSR 서버는 CDN 캐싱, Redis, Nginx 리버스 프록시 등을 함께 사용해 렌더링 결과를 일정 시간 캐싱하는 전략이 필수입니다.

 

2. 구현 복잡도 증가

CSR은 “프론트엔드만 잘 만들면 끝”이지만, SSR은 “서버와 클라이언트 양쪽 코드가 맞물려야 하는 구조”입니다.
렌더링 환경이 두 번 존재하기 때문에 데이터 패칭 시점, 라우팅, 상태 동기화(State Sync), 하이드레이션 오류 등 신경 써야 할 부분이 많습니다.

특히 서버 전용 코드(API 키, 보안 로직 등)가 클라이언트로 노출되지 않도록 주의해야 합니다.

 

3. 배포 및 인프라 부담

SSR을 적용하려면 Node.js 기반 서버 환경이 필요합니다.

정적 파일을 CDN에 올리는 CSR/SSG보다 배포 파이프라인과 서버 관리가 복잡해지죠. 또한, SSR 서버는 클라우드 스케일링(오토스케일링) 구조를 함께 설계해야 합니다.

 

✔️ 실무 기준: 언제 SSR을 선택할까?

상황 권장 렝더링 방식
검색 유입이 중요한 콘텐츠 페이지 SSR
로그인 후 내부 페이지 (대시보드 등) CSR
뉴스, 상품 상세, 블로그 등 SSR
실시간 데이터가 자주 바뀌는 페이지 SSR + CSR 하이브리드

실무에서는 보통 SSR과 CSR을 혼합해 사용하는 하이브리드 렌더링 구조를 채택합니다.

초기 로딩은 SSR로 빠르게 보여주고, 이후 페이지 전환이나 상호작용은 CSR로 처리하는 방식입니다.

이런 구조가 UX, SEO, 서버 부하의 균형을 가장 잘 맞춥니다.

 

SSR은 SEO, 초기 렌더링 속도, 소셜 미리보기 등에서 큰 장점을 제공하지만 그만큼 서버 자원과 개발 복잡도가 뒤따릅니다.
따라서 “모든 페이지에 SSR을 적용”하기보다는 “검색 유입이 필요한 페이지만 SSR, 나머지는 CSR” 식의 전략적 접근이 필요합니다.
결국 SSR의 핵심은 “속도와 검색 최적화를 위한 서버 주도 렌더링”이며, 그 선택은 프로젝트의 성격과 목표에 따라 달라져야 합니다.

 

반응형

 

3. SSR의 동작 흐름과 구현 구조

SSR(Server Side Rendering)은 단순히 서버에서 HTML을 “한 번” 만들어 주는 게 아닙니다.

사실 그 내부에서는 요청(Request) - 데이터 패칭(Data Fetching) - 렌더링(Rendering) - 하이드레이션(Hydration) 이라는 여러 단계를 거쳐야 비로소 “사용자에게 보이는 완성된 페이지”가 만들어집니다.
이 과정을 이해하면 SSR의 구조와 특징이 한눈에 들어옵니다.

 

🔷 SSR의 기본 흐름

SSR은 아래의 5단계로 작동합니다.

1. 사용자 요청 (Request)

▸ 사용자가 /posts/1 같은 URL을 입력하거나, SSR 페이지 링크를 클릭합니다.
▸ 브라우저는 해당 페이지를 요청(Request)으로 서버에 보냅니다.

 

2. 데이터 패칭 (Data Fetching)

▸ 서버는 이 요청을 받아 DB나 외부 API로부터 필요한 데이터를 불러옵니다.
▸ 예를 들어 블로그 글이라면 getPost(1) API를 호출해 제목과 내용을 가져오겠죠.

 

3. 서버 렌더링 (Server Render)

▸ 가져온 데이터를 기반으로 서버에서 HTML을 생성합니다.
▸ 이때 React, Vue 같은 프레임워크는 서버에서 컴포넌트를 문자열(HTML) 로 변환합니다.
▸ 즉, 브라우저가 렌더링하기 전에 이미 완성된 페이지 HTML이 만들어지는 것입니다.

 

4. 응답 전송 (Response)

▸ 서버는 완성된 HTML을 클라이언트(브라우저)로 전송합니다.
▸ 브라우저는 즉시 그 HTML을 화면에 렌더링하여 사용자에게 표시합니다.

 

5. 하이드레이션 (Hydration)

▸ 브라우저가 HTML을 보여준 뒤, JS 번들이 다운로드되어 실행됩니다.
▸ 이때 기존 HTML과 컴포넌트 구조를 “연결(bind)”하는 과정을 하이드레이션이라 부릅니다.
▸ 이 과정을 거치면 화면이 단순한 정적 HTML이 아니라 실시간 상호작용 가능한 SPA(Single Page Application)가 됩니다.

 

🔷 React (Next.js) 기반 SSR 구조

Next.js는 React 기반의 SSR 프레임워크로, 페이지별로 SSR을 활성화할 수 있도록 설계되어 있습니다.
가장 대표적인 방식이 getServerSideProps() 입니다.
이 함수가 존재하면 Next.js는 해당 페이지를 SSR 모드로 렌더링 합니다.

// pages/index.tsx
export async function getServerSideProps() {
  const res = await fetch('https://api.example.com/posts')
  const posts = await res.json()

  return { props: { posts } }
}

export default function Home({ posts }) {
  return (
    <main>
      <h1>게시글 목록</h1>
      <ul>
        {posts.map(p => <li key={p.id}>{p.title}</li>)}
      </ul>
    </main>
  )
}

1. 사용자가 / 페이지를 요청하면 Next.js 서버가 이 페이지를 감지
2. getServerSideProps() 실행 → API에서 데이터 패칭
3. 서버가 HTML을 생성하여 클라이언트로 전송
4. 브라우저가 HTML을 즉시 표시
5. 이후 JS가 하이드레이션 되어 이벤트 연결

결과적으로 사용자는 페이지를 클릭하자마자 “완성된 게시글 목록”을 바로 볼 수 있습니다.

 

🔷Vue (Nuxt.js) 기반 SSR 구조

Vue 진영의 대표 SSR 프레임워크는 Nuxt.js입니다. Nuxt는 SSR을 프레임워크 기본 모드로 내장하고 있어 별도 설정 없이도 서버 렌더링이 활성화됩니다.

<!-- pages/index.vue -->
<script setup>
const { data: posts } = await useFetch('https://api.example.com/posts')
</script>

<template>
  <section>
    <h1>게시글 목록</h1>
    <ul>
      <li v-for="p in posts" :key="p.id">{{ p.title }}</li>
    </ul>
  </section>
</template>

1. Nuxt 서버가 useFetch()를 실행하여 데이터를 서버에서 먼저 받아옴
2. Vue 컴포넌트를 서버에서 렌더링 → HTML 생성
3. 완성된 HTML을 클라이언트로 전달
4. 클라이언트가 이를 표시하고, JS 실행 후 하이드레이션 수행

Nuxt는 SSR을 매우 자연스럽게 처리하기 때문에 Vue 개발자 입장에서는 “CSR 개발 방식 그대로” 작성하면서 SSR의 이점을 얻을 수 있습니다.

 

🔷 SSR 렌더링 플로우 다이어그램

Client (Browser)
      │
      ▼
 [HTTP Request] ──────▶ [SSR Server]
                          │
                          ├─ Data Fetching (DB, API)
                          ├─ HTML Rendering (React/Vue)
                          ▼
                     [Rendered HTML Response]
      │
      ▼
 [Initial Paint: 즉시 화면 표시]
      │
      ▼
 [Hydration: JS 이벤트 연결 → SPA 활성화]

 

4. 실무에서의 SSR 적용 전략

SSR(Server Side Rendering)을 이론적으로 이해하는 것과, 실제 서비스에 적용하는 것은 완전히 다른 이야기입니다.

실무에서는 “모든 페이지에 SSR을 쓰자”는 접근보다는, “어떤 페이지에 SSR을 적용해야 가장 효율적인가?”를 판단하는 것이 핵심입니다.


이번 섹션에서는 SSR을 도입할 때의 전략, 캐싱, 하이브리드 구조, 보안 포인트를 단계별로 살펴봅니다.

 

🔷 Hybrid Rendering: SSR + CSR 혼합 전략

현대의 대부분의 웹 서비스는 SSR과 CSR을 혼합한 구조를 사용합니다.
이를 흔히 Hybrid Rendering이라 부르며, 초기 페이지는 SSR로 빠르게 렌더링하고, 이후 페이지 이동은 CSR로 처리합니다.

1. 사용자가 /products/1 페이지를 요청
2. SSR로 HTML을 생성 → 첫 화면 즉시 표시
3. 이후 /products/2로 이동 시, CSR로 내부 전환 (JS 라우팅)
4. 전체 페이지 새로고침 없이 빠른 화면 전환
이 구조는 SEO, UX, 성능을 모두 고려한 실무형 타협점입니다.

 

✔️ Next.js / Nuxt.js 모두 Hybrid 구조 지원

▸ Next.js: 기본적으로 모든 페이지가 하이브리드로 동작 (SSR + CSR 자동 전환)

▸ Nuxt.js: ssr: true 상태에서도 페이지 간 전환은 CSR 방식으로 처리

즉, SSR을 설정했다고 해서 항상 모든 요청이 서버 렌더링되는 건 아닙니다.
첫 로딩만 SSR, 나머지는 CSR이죠. 이것이 바로 하이브리드 렌더링의 핵심 철학입니다.

 

🔷 SSR 성능 최적화 전략

SSR을 도입하면 가장 먼저 부딪히는 문제가 바로 서버 부하와 응답 속도입니다.

요청마다 렌더링을 수행하기 때문에, 성능을 유지하려면 적절한 캐싱 전략과 CDN 구성이 필수입니다.

 

1. HTML 캐싱

▸ 동일한 요청에 대해 매번 SSR을 수행할 필요는 없습니다.

▸ Cloudflare, Vercel Edge, Nginx Reverse Proxy 등을 이용해 SSR 결과 HTML을 일정 시간 캐싱하면 서버 부하를 크게 줄일 수 있습니다.

# Nginx 예시
location / {
  proxy_cache STATIC_HTML;
  proxy_cache_valid 200 10s;
  proxy_pass http://localhost:3000;
}

짧은 TTL(Time To Live)을 설정하면, “10초마다 새로운 SSR 렌더링”처럼 신선도를 유지하면서도 부하를 완화할 수 있습니다.

 

2. 데이터 캐싱

▸ SSR 렌더링 과정에서 매번 DB/API 요청을 보내면 성능이 급격히 떨어집니다.

▸ Redis, Apollo Client cache, Prisma Data Proxy 등을 활용해 자주 조회되는 데이터를 캐싱하는 것이 좋습니다.

 

3. CDN(Content Delivery Network)

▸ JS 번들, CSS, 이미지 등 정적 리소스는 서버가 아닌 CDN을 통해 전 세계 엣지 서버에서 서빙해야 합니다.

▸ Cloudflare, AWS CloudFront, Vercel, Netlify 모두 SSR 친화적인 CDN을 제공합니다.

SSR은 CPU 리소스를 쓰는 구조이므로, 정적 리소스는 절대 SSR 서버에서 직접 제공하지 않도록 분리하는 것이 원칙입니다.

 

🔷 보안과 운영에서의 주의사항

SSR은 서버 코드가 직접 실행되기 때문에, 보안 측면에서도 몇 가지 주의해야 할 포인트가 있습니다.

 

1.  API Key / 환경변수 노출 금지

▸ SSR에서는 서버 전용 환경변수(process.env)를 사용할 수 있지만, 클라이언트로 전달할 때는 반드시 직접 노출되지 않도록 필터링해야 합니다.
▸ 예: getServerSideProps 내부에서만 API Key 사용 → 클라이언트에는 결과만 전달

export async function getServerSideProps() {
  const data = await fetch(`https://api.example.com/posts?key=${process.env.API_KEY}`)
  return { props: { data } } // key는 클라이언트에 전달되지 않음
}

 

2. 상태 관리(Store) 동기화

SSR에서 상태 관리 도구(Vuex, Zustand, Pinia 등)를 사용할 때는, 서버와 클라이언트의 상태가 불일치하면 하이드레이션 오류가 발생할 수 있습니다.

예: 서버에서는 3개의 게시글을 렌더링 했는데,
클라이언트 상태에는 2개만 있으면 React는 “DOM mismatch” 경고를 띄웁니다.

이를 방지하려면 서버 렌더링 직후 초기 상태(initial state)를 JSON으로 직렬화해 클라이언트에 함께 전달해야 합니다.

// React 예시
<script dangerouslySetInnerHTML={{
  __html: `window.__INITIAL_STATE__ = ${JSON.stringify(initialState)}`
}} />

 

3. 보안 헤더 설정

SSR 서버는 단순 정적 서버가 아니기 때문에, 보안 헤더(Security Header) 설정이 매우 중요합니다.

▸ X-Frame-Options: DENY → Clickjacking 방지
▸ Content-Security-Policy → 외부 스크립트 제어
▸ X-XSS-Protection → 크로스 스크립팅 방어

Node.js 서버(Nest.js, Express, Fastify)는 helmet 패키지로 쉽게 적용할 수 있습니다.

npm install helmet
import helmet from 'helmet'
app.use(helmet())

 

🔷 SSR 운영 및 배포 환경

SSR 앱은 “서버 기반 앱”이기 때문에 정적 사이트 배포(예: GitHub Pages)가 아닌 서버 런타임 환경이 반드시 필요합니다.

배포방식 설명 예시
Serverful (Node 서버 직접 운영) Express, PM2, Nginx와 함께 직접 구동 자체 서버 or AWS EC2
Serverless (Lambda 기반) 요청 시 동적으로 SSR 수행 Vercel, Netlify, Cloudflare Pages
Edge Rendering CDN Edge 노드에서 SSR 수행 (초저지연) Vercel Edge Functions, Cloudflare Workers
추천:
중소 규모 서비스 → Vercel / Netlify (서버리스 SSR)
대규모 트래픽 서비스 → Node.js 서버 + CDN 캐싱 조합

 

 

반응형

 

 

※ 게시된 글 및 이미지 중 일부는 AI 도구의 도움을 받아 생성되거나 다듬어졌습니다.

반응형