---
term: 'SSR vs. CSR vs. SSG'
seoTitle: 'SSR vs. CSR vs. SSG: 렌더링 패턴, SEO, 성능 지표'
headline: 'SSR vs. CSR vs. SSG: 웹 렌더링의 작동 방식'
slug: ssr-vs-csr-vs-ssg
category: frontend-web
shortDefinition: 'SSR vs. CSR vs. SSG는 HTML이 어디서 언제 생성되는지(빌드 시점, 서버, 브라우저)에 따라 렌더링 전략을 비교하는 것입니다.'
relatedTerms:
  - jamstack
  - cdn-content-delivery-network
  - progressive-web-app-pwa
  - api
contrastsWith:
  - jamstack
aboutTerms:
  - 'Hydration'
  - 'ISR & Streaming'
  - 'TTFB / FCP / TTI'
faq:
  - question: 'CSR(클라이언트 측 렌더링)이란 무엇입니까?'
    answer: '서버는 거의 비어 있는 HTML 셸과 JavaScript 번들을 보내고, 브라우저가 JS를 다운로드하고 파싱하고 실행한 뒤 API에서 데이터를 가져와 페이지를 만듭니다. JavaScript가 실행될 때까지 사용자는 빈 화면이나 로딩 스피너를 봅니다. 상호작용성은 가장 좋지만 초기 로드와 SEO는 가장 불리합니다.'
  - question: 'SSR(서버 측 렌더링)이란 무엇입니까?'
    answer: '서버가 요청마다 코드를 실행하고 데이터를 가져와 완전한 HTML을 생성하고, 바로 그릴 수 있는 문서를 보낸 뒤 상호작용을 위해 하이드레이션합니다. SEO에 강하고 첫 페인트가 빠르며 데이터가 항상 최신이지만, 그 대가로 서버 연산이 들고 TTFB(첫 바이트까지의 시간)가 길어집니다.'
  - question: 'SSG(정적 사이트 생성)란 무엇입니까?'
    answer: '모든 페이지의 HTML을 빌드 시점에 정적 파일로 미리 만들어 CDN에서 제공하며, 요청마다 서버가 할 일이 없습니다. 가장 빠르고 저렴하며 SEO에 가장 유리한 선택지입니다. 다만 데이터는 마지막 빌드 시점만큼만 최신이고, 미리 알 수 없거나 매우 동적인 경로에는 잘 맞지 않습니다.'
  - question: '세 방식의 차이는 무엇입니까?'
    answer: 'HTML이 어디서 언제 생성되는가입니다. 빌드 시점(SSG), 요청마다 서버(SSR), 런타임에 브라우저(CSR) 중 하나입니다. SEO, 성능, 데이터 최신성, 비용 등 나머지는 모두 이 하나의 선택에서 따라 나옵니다.'
  - question: 'SEO에는 어떤 렌더링 전략이 가장 좋습니까?'
    answer: 'SSG와 SSR입니다. 크롤러가 완성된 HTML을 받기 때문입니다. CSR은 가장 위험합니다. 봇이 콘텐츠를 보려면 JavaScript를 실행해야 하므로 색인이 늦어지거나 누락될 수 있습니다. 미묘한 점은 최신 크롤러가 JavaScript를 렌더링하기는 하지만 크롤링 예산 범위 안에서만 한다는 것입니다. 따라서 CSR은 색인될 필요가 없는 화면에는 문제가 없지만, 검색 순위가 필요한 콘텐츠에는 도박입니다.'
  - question: '하이드레이션이란 무엇입니까?'
    answer: '이미 렌더링된 서버 HTML에 JavaScript(이벤트 리스너와 상태)를 붙여 정적으로 보이는 페이지를 상호작용 가능하게 만드는 과정입니다. 함정은 JS를 여전히 다운로드하고 파싱하고 실행해야 한다는 점입니다. 그래서 페이지가 준비된 것처럼 보이면서도 클릭되지 않는 상태가 이어질 수 있고, 첫 페인트가 빨랐더라도 TTI(상호작용 가능 시간)는 늦어집니다.'
  - question: 'SSR과 SSG는 각각 언제 사용해야 합니까?'
    answer: '모두에게 같고 거의 바뀌지 않는 콘텐츠(문서, 블로그, 마케팅)에는 SSG를 사용합니다. 개인화되거나 인증이 필요하거나, 빌드 시점의 데이터가 낡을 만큼 자주 바뀌는 페이지에는 SSR을 사용합니다. 기본 권장 사항은 SSG를 우선하고, 요청 단위의 최신성이 필요한 곳에서만 SSR을 쓰는 것입니다.'
  - question: '앱 하나에 전략 하나만 써야 합니까?'
    answer: '아니요. 현대적인 방식은 경로 단위, 심지어 컴포넌트 단위입니다. 정적 마케팅 페이지, 재생성되는 카탈로그 페이지, 서버에서 렌더링되는 대시보드, 클라이언트에서 렌더링되는 위젯이 모두 한 앱 안에 공존할 수 있습니다. 렌더링은 사이트 전체에 대해 한 번 내리는 결정이 아니라 페이지마다 내리는 결정입니다.'
codeLanguages: [javascript, dart, swift, kotlin]
externalAuthorities:
  - name: 'Client-side rendering (CSR) — MDN Web Docs'
    url: 'https://developer.mozilla.org/en-US/docs/Glossary/CSR'
  - name: 'Server-side rendering (SSR) — MDN Web Docs'
    url: 'https://developer.mozilla.org/en-US/docs/Glossary/SSR'
  - name: 'Rendering patterns — patterns.dev'
    url: 'https://www.patterns.dev/'
  - name: 'Static site generator — Wikipedia'
    url: 'https://en.wikipedia.org/wiki/Static_site_generator'
cta:
  title: '하나의 API, 어떤 렌더링 전략이든'
  text: 'Back4app의 REST와 GraphQL API는 빌드 시점의 SSG, 요청마다의 SSR, 브라우저의 CSR에 그대로 데이터를 공급합니다. 렌더링은 경로마다 고르고, 백엔드는 그대로 둡니다.'
  linkText: '무료로 시작하기'
  linkUrl: 'https://www.back4app.com/signup'
author: 'Back4app Engineering'
publishedDate: '2026-11-03'
translationKey: ssr-vs-csr-vs-ssg
---

**SSR vs. CSR vs. SSG는 HTML이 어디서 언제 생성되는지(빌드 시점, 서버, 브라우저)에 따라 렌더링 전략을 비교하는 것입니다.** SSR은 서버 측 렌더링(server-side rendering), CSR은 클라이언트 측 렌더링(client-side rendering), SSG는 정적 사이트 생성(static site generation)입니다. *어디서 언제*라는 이 하나의 축이 SEO, 성능, 데이터 최신성, 비용을 결정하며, 나머지는 모두 그 결과입니다. 그리고 프론트엔드 가이드들이 묻어 두는, 백엔드 개발자 입장의 정리가 있습니다. **렌더링은 프론트엔드의 관심사이고, 데이터는 백엔드의 관심사입니다.** 세 전략 모두 같은 [API](/glossary/ko/api/)를 호출하며, 호출하는 순간만 다릅니다.

## 핵심 요약

| 질문 | 답변 |
| --- | --- |
| 기준 축 | HTML이 *어디서 언제* 만들어지는가: 빌드 · 서버 · 브라우저 |
| CSR | 브라우저가 만듦. 상호작용성은 최고, 첫 로드와 SEO는 최악 |
| SSR | 서버가 요청마다 만듦. 최신 데이터, SEO에 강함, TTFB가 더 높음 |
| SSG | 빌드 시점에 미리 만들어 [CDN](/glossary/ko/cdn-content-delivery-network/)에서 제공. 가장 빠르고 저렴하며, 다시 빌드할 때까지 낡은 상태 |
| 관점 전환 | 같은 [API](/glossary/ko/api/), 세 가지 호출 시점. 앱 단위가 아니라 경로 단위 |

## 같은 데이터, 세 가지 호출 시점

**JavaScript:**

```javascript
// JavaScript — the SAME API call, consumed three ways.
// Rendering is a FRONTEND choice; the data is a BACKEND concern.
async function getPosts() {
  const q = new Parse.Query('Post').equalTo('published', true).limit(20);
  return q.find(); // one backend endpoint — the ONLY thing that changes is WHEN
}

// SSG — called at BUILD time; data baked into static HTML, served from a CDN.
// SSR — called PER REQUEST on the server; fresh HTML sent to the browser.
// CSR — called FROM THE BROWSER after load; the client builds the DOM.
// You don't change the backend to switch rendering — only when/where you fetch.
```

**Flutter:**

```dart
// Flutter / Dart — Back4app Flutter SDK
// Whatever the rendering strategy, the data comes from one backend API.
Future<List<ParseObject>> getPosts() async {
  final q = QueryBuilder<ParseObject>(ParseObject('Post'))
    ..whereEqualTo('published', true)
    ..setLimit(20);
  return (await q.query()).results?.cast<ParseObject>() ?? [];
}
// SSG fetches at build, SSR fetches per request, CSR fetches in the client —
// the endpoint is identical; only the timing and location differ.
```

**Swift:**

```swift
// Swift — Back4app Swift SDK
// Whatever the rendering strategy, the data comes from one backend API.
func getPosts() async throws -> [Post] {
    try await Post.query("published" == true).limit(20).find()
}
// SSG fetches at build, SSR fetches per request, CSR fetches in the client —
// the endpoint is identical; only the timing and location differ.
```

**Kotlin:**

```kotlin
// Kotlin — Back4app Android SDK
// Whatever the rendering strategy, the data comes from one backend API.
fun getPosts(): List<ParseObject> {
    val q = ParseQuery.getQuery<ParseObject>("Post")
    q.whereEqualTo("published", true)
    q.limit = 20
    return q.find()
}
// SSG fetches at build, SSR fetches per request, CSR fetches in the client —
// the endpoint is identical; only the timing and location differ.
```

`getPosts()` 하나, 백엔드 엔드포인트 하나입니다. **SSG**는 이를 *빌드 시점*에 호출해 결과를 정적 HTML에 구워 넣고, **SSR**은 *요청마다 서버에서* 호출해 최신 HTML을 보내며, **CSR**은 로드 후 *브라우저에서* 호출합니다. 렌더링을 바꾸려고 백엔드를 바꿀 일은 없습니다. 데이터를 가져오는 시점과 장소만 바뀝니다. 이 사실이 헷갈리는 삼자 비교를 하나의 결정으로 바꿔 줍니다.

## SSR vs. CSR vs. SSG 나란히 비교

```mermaid
flowchart LR
  accTitle: CSR, SSR, SSG에서 HTML이 생성되는 위치
  accDescr: 클라이언트 측 렌더링에서는 서버가 빈 셸과 JavaScript 번들을 보내고, 브라우저가 API에서 데이터를 가져와 페이지를 만듭니다. 서버 측 렌더링에서는 서버가 요청마다 API에서 데이터를 가져와 완전한 HTML을 보내고, 이후 하이드레이션합니다. 정적 사이트 생성에서는 빌드 시점에 API로부터 HTML을 미리 만들어 CDN에서 제공합니다. 세 방식 모두 같은 백엔드 API를 읽습니다.
  API[("백엔드 API")] -->|"빌드 시점에"| SSG["SSG → 정적 HTML → CDN"]
  API -->|"요청마다, 서버에서"| SSR["SSR → 완전한 HTML → 하이드레이션"]
  API -->|"브라우저에서"| CSR["CSR → 셸 + JS → DOM 구성"]
```

| | CSR | SSR | SSG |
| --- | --- | --- | --- |
| HTML 생성 위치 | 브라우저 | 서버, 요청마다 | 빌드 시점 |
| TTFB | 빠름 | **더 높음**(먼저 렌더링) | **가장 빠르고 일정함** |
| 첫 페인트(FCP) | 느림 | 빠름 | 빠름 |
| 상호작용 가능(TTI) | 느림 | 하이드레이션 후 | 하이드레이션 후 |
| SEO | 가장 위험 | 강함 | 강함 |
| 데이터 최신성 | 실시간 | 실시간 | 마지막 빌드 기준 |
| 비용 | 서버 부담 적음 | 요청마다 서버 비용 | 가장 저렴(정적) |
| 적합한 대상 | 대시보드, 앱 | 개인화, 최신 데이터 | 콘텐츠, 문서, 마케팅 |

## 성능 지표, 솔직하게

어떤 비교 글도 깔끔하게 말하지 않는 트레이드오프입니다. **SSG**는 TTFB(첫 바이트까지의 시간)에서 확실하고 일관되게 이깁니다. CDN이 미리 빌드된 파일을 그대로 돌려주기 때문입니다. **SSR**은 TTFB를 *높입니다*(서버가 응답하기 전에 렌더링해야 하므로). 그래도 첫 페인트에서는 CSR보다 빠르고, 최신 데이터를 보냅니다. **CSR**은 TTFB가 빠르지만(셸이 아주 작으므로) 첫 페인트와 TTI(상호작용 가능 시간)가 느립니다. 번들이 실행될 때까지 아무것도 보이지 않기 때문입니다. 그리고 모두가 얼버무리는 한 가지가 있습니다. **SSR과 SSG는 TTI를 해결하지 못합니다.** 둘 다 준비된 *것처럼 보이는* HTML을 보내지만, 그 뒤에 **하이드레이션**, 즉 상호작용을 붙이기 위해 JavaScript를 다운로드하고 파싱하고 실행하는 과정이 어차피 실행됩니다. 이것이 "준비된 것처럼 보이지만 클릭되지 않는" 간극이며, 전송되는 JS의 양이 상호작용성의 진짜 비용인 이유입니다. 그래서 JS를 덜 보내는 아일랜드, 부분 하이드레이션, 서버 컴포넌트가 등장했습니다.

## 2026년의 스펙트럼: ISR, 스트리밍, RSC

세 가지 구분은 교육용 단순화이고, 실제 프로덕션은 스펙트럼입니다. **ISR**(증분 정적 재생성, incremental static regeneration)은 정적 페이지를 제공하되 일정 간격이나 요청에 따라 페이지를 재생성합니다. SSG의 속도에 주기적인 최신성을 더하는 대신 가끔 낡은 페이지가 보이는 대가를 치릅니다. **스트리밍 SSR**은 HTML이 생성되는 대로 청크 단위로 보내므로, 셸은 수십 밀리초 안에 그려지고 느린 콘텐츠는 그 뒤로 스트리밍됩니다. **서버 컴포넌트**(RSC)는 서버에서만 실행되고, 상호작용이 없는 부분에는 JavaScript를 *전혀* 보내지 않으며, 데이터를 직접 읽을 수 있습니다. 하이드레이션 비용에 대한 가장 새로운 해답입니다. 이 중 어느 것도 백엔드 계약을 바꾸지 않습니다. *HTML이 언제 만들어지고 그 뒤에 JS가 얼마나 따라오는지*를 더 세밀하게 제어할 뿐이며, 이는 이 항목 전체가 다루는 바로 그 축입니다.

## 앱 단위가 아니라 경로 단위

"무엇을 써야 하나?" 논쟁의 대부분을 해소하는 사고의 전환이 있습니다. **사이트 전체에 전략 하나를 고르는 것이 아닙니다.** 하나의 앱이 여러 전략을 섞는 일은 흔합니다. 정적으로 생성한 마케팅 홈페이지, ISR로 재생성되는 상품 카탈로그, 서버에서 렌더링되는 개인화 대시보드, 클라이언트에서 렌더링되는 인터랙티브 위젯이 각 경로의 필요에 따라 선택됩니다. 질문은 결코 "내 앱에 SSR, CSR, SSG 중 무엇을?"이 아니라 "이 페이지에는 무엇을?"이며, 답은 페이지의 데이터를 따릅니다. 모두에게 같고 안정적이면 정적, 개인화되거나 최신이어야 하면 서버, 로그인 뒤에 있고 상호작용이 많으면 클라이언트입니다.

## 페이지마다 어떤 전략을 선택해야 할까? 결정 매트릭스

| 페이지 유형 | 렌더링 |
| --- | --- |
| 마케팅, 랜딩, 블로그, 문서 | SSG |
| 상품 카탈로그, 뉴스, 피드 | ISR(정적 + 주기적 갱신) |
| 개인화, 인증 필요, 장바구니, 검색 | SSR(또는 스트리밍) |
| 대시보드, 사내 도구 | CSR |
| 실시간, 고도로 인터랙티브 | CSR + [실시간 데이터](/glossary/ko/real-time-live-queries/) |
| SEO가 핵심인 콘텐츠 | CSR은 피함. 서버 렌더링 또는 미리 빌드 |

## 일반적인 사용 사례

- **콘텐츠 사이트**: SSG와 [CDN](/glossary/ko/cdn-content-delivery-network/)으로 즉시 뜨고 크롤러 친화적인 페이지를 제공합니다([JAMstack](/glossary/ko/jamstack/) 패턴).
- **이커머스**: ISR 카탈로그 페이지, SSR 장바구니와 결제, CSR 인터랙티브 필터. 하나의 스토어에 세 가지 전략입니다.
- **SaaS 대시보드**: 로그인 뒤의 CSR. SEO는 중요하지 않고 상호작용성이 중요합니다.
- **뉴스와 출판**: SEO를 유지하면서 최신성을 얻기 위한 SSR 또는 ISR입니다.
- **[PWA](/glossary/ko/progressive-web-app-pwa/)**: 렌더링된 셸에 클라이언트 측 상호작용과 오프라인 캐싱을 더합니다.

## 한계와 트레이드오프

- **CSR의 SEO 위험은 실재하지만 과장되어 있습니다.** 크롤러는 예산 안에서 JavaScript를 렌더링합니다. 색인될 필요가 없는 화면에서는 CSR이 괜찮지만, 색인되어야 하는 화면에서는 도박입니다. 절대론이 아니라 뉘앙스의 문제입니다.
- **SSR은 서버 연산 비용이 듭니다.** 모든 요청을 렌더링하면 CDN에서 제공되는 정적 파일에는 없는 TTFB와 인프라 비용이 발생합니다.
- **SSG의 최신성 지연.** 빌드 시점의 데이터는 다음 빌드까지 낡은 상태로 남습니다. 크거나 빠르게 바뀌는 사이트에는 ISR이나 긴 빌드가 필요합니다.
- **하이드레이션은 숨은 비용입니다.** 서버에서 렌더링한 HTML도 상호작용을 위해 JS를 보내야 합니다. 첫 페인트가 빠르다고 첫 *클릭*까지 빠른 것은 아닙니다.
- **섞으면 인지 부하가 늘어납니다.** 경로 단위 렌더링은 강력하지만, 한 앱 안에서 여러 데이터 조회 시점을 함께 고려해야 한다는 뜻입니다. 유연성에는 복잡성 비용이 따릅니다.

## Back4app에서의 렌더링

Back4app은 관리형 데이터베이스, 자동 생성되는 REST 및 GraphQL API, 인증, 파일 스토리지, Cloud Code 서버리스 함수를 결합한 오픈소스 Backend as a Service(BaaS) 플랫폼입니다. Back4app은 렌더링 방식을 어떻게 고르든 변하지 않는 기반입니다. [REST와 GraphQL API](/glossary/ko/auto-generated-database-apis/)가 **빌드 시점의 SSG**, **서버에서 요청마다의 SSR**, **브라우저에서의 CSR**에 데이터를 공급합니다. 코드 탭이 보여 주는 동일한 엔드포인트를 세 가지 다른 순간에 소비하는 것이므로, 경로의 전략을 바꿔도 백엔드는 건드리지 않습니다. 이 글 첫머리에서 제시한 관점 전환이 여기서 실질적인 이점이 됩니다. 렌더링은 프론트엔드의 결정이고 데이터는 자체 [인증](/glossary/ko/authentication-vs-authorization/)과 [권한](/glossary/ko/access-control-lists-acl/)을 갖춘 하나의 안정적인 API 뒤에 있으므로, 한 팀이 같은 Back4app 백엔드를 대상으로 블로그는 미리 빌드하고, 대시보드는 서버에서 렌더링하고, 앱 셸은 클라이언트에서 렌더링할 수 있습니다. 페이지마다 고르고, 그 아래는 아무것도 바꾸지 않습니다.
