본문 바로가기
Tech Notes

화면은 누가 그리나 — SSR · CSR, 그리고 그 사이의 것들

by miracle-tech 2026. 6. 1.
728x90
반응형
화면은 누가 그리나 — SSR · CSR, 그리고 그 사이의 것들
프론트엔드 · 1인 개발자 메모

화면은 누가 그리나 — SSR · CSR, 그리고 그 사이의 것들

"Next.js 쓰면 SSR 아니에요?"라는 질문에서 시작한, 렌더링이 일어나는 '장소'에 대한 지형도 정리.

2026-06-01 · 약 10분 소요

들어가며: "Next.js 쓰면 SSR 아니에요?"

앱인토스 앱은 전부 React로 짜는데, 이게 다 CSR이에요. 그런데 블로그나 랜딩 페이지 얘기가 나오면 갑자기 "그건 SSR이 유리하지"라는 말이 나오죠. 누가 물었어요. "같은 React인데 왜 어떤 건 CSR이고 어떤 건 SSR이에요? Next.js 쓰면 그냥 SSR 아니에요?"

여기엔 흔한 오해가 하나 있어요. SSR과 CSR을 프레임워크 이름이나 좋고 나쁨의 문제로 보는 것. 사실 둘의 차이는 딱 하나예요 — "HTML을 누가, 어디서 만드느냐." 서버가 만들면 SSR, 브라우저가 만들면 CSR. 그게 전부고, 나머지는 거기서 파생되는 결과들이에요.

이 글의 결론을 먼저: 렌더링 방식 선택은 "뭐가 더 좋냐"가 아니라 "첫 화면이 검색·속도에 걸리느냐, 아니면 로그인 뒤 앱처럼 쓰이느냐"에서 갈립니다. 앱인토스 앱이 전부 CSR이어도 멀쩡한 이유, 블로그가 정적이어야 하는 이유가 거기 있어요.


가장 중요한 한 갈래: HTML을 누가 만드나

다른 건 다 잊어도 이것만 기억하면 절반은 끝나요. 사용자가 주소를 치고 화면이 보이기까지, "내용이 담긴 HTML"을 누가 만드느냐가 갈림길입니다.

CSR (Client-Side Rendering)

서버는 거의 빈 HTML 한 장 + JS 번들만 보냅니다. 브라우저가 그 JS를 내려받아 실행하면, 그제서야 화면이 그려져요. 즉 그리는 주체가 브라우저. React로 만든 일반 SPA(앱인토스 앱 포함)가 여기예요.

SSR (Server-Side Rendering)

서버가 요청을 받을 때마다 내용이 다 채워진 완성 HTML을 만들어서 보냅니다. 브라우저는 받자마자 글씨가 보여요. 그다음 JS가 붙어서(=하이드레이션) 버튼이 눌리는 '살아있는' 페이지가 됩니다. 그리는 주체가 서버. Next.js의 서버 렌더링이 대표적이에요.

CSR — 브라우저가 그린다 브라우저 서버 요청 빈 HTML + JS 번들 JS 다운로드·실행 → 화면 그림 첫 화면까지 ↑ 느림 이후 이동 ↑ 빠름 SSR — 서버가 그린다 브라우저 서버 요청 HTML 완성 완성된 HTML 첫 화면 ↑ 바로 보임 하이드레이션(JS 부착) 서버 부담 ↑
CSR(브라우저가 JS 받아 그림) vs SSR(서버가 완성 HTML을 보냄)
한 줄 요약: "검색에 걸리고 첫 화면이 빨라야 함"이면 서버가 미리 그린다(SSR/정적). "로그인 뒤 앱처럼 계속 쓰는 화면"이면 브라우저가 그린다(CSR).

CSR을 자세히 — 빈 도화지를 받아 직접 그린다

CSR의 첫 응답은 사실상 <div id="root"></div> 한 줄과 JS 묶음이에요. 브라우저가 JS를 다 받아 실행하기 전까지 사용자는 흰 화면(혹은 로딩 스피너)을 봅니다.

  • 첫 화면은 느립니다. JS 다운로드 → 파싱 → 실행 → 데이터 fetch → 렌더, 이 과정을 다 거쳐야 글자가 보여요. 번들이 크면 더 늦어집니다.
  • 이후는 빠릅니다. 한 번 떠 있으면 페이지 이동 시 서버에서 HTML을 다시 안 받고, 필요한 데이터(JSON)만 가져와 화면 일부만 갈아끼워요. 앱처럼 매끄럽죠.
  • SEO엔 불리합니다. 검색 크롤러가 받는 건 빈 HTML이에요. 요즘 구글은 JS를 실행해 내용을 읽기도 하지만, 비용·지연·누락 위험이 있어 "확실히 걸려야 하는 페이지"엔 약점입니다.
  • 서버는 편합니다. 정적 파일(HTML·JS) 한 벌을 CDN에 올려두면 끝. 요청마다 서버가 일할 게 없어요.

SSR을 자세히 — 완성품을 받아 손질만 한다

SSR은 서버가 요청을 받을 때마다 데이터까지 채운 HTML을 만들어 보냅니다. 그래서 브라우저는 첫 응답에 이미 글자가 다 들어있어요.

  • 첫 화면이 빠릅니다. 받자마자 보이니 체감 속도(FCP)가 좋고, 느린 기기일수록 차이가 커요.
  • SEO에 강합니다. 크롤러가 완성된 HTML을 그대로 읽으니 내용이 100% 노출돼요. 검색 유입이 중요한 페이지의 정석입니다.
  • 대신 서버가 일합니다. 요청마다 렌더링을 도니 서버 비용·부하가 생기고, 서버 처리가 느리면 TTFB(첫 바이트까지 시간)가 늘어요.
  • 하이드레이션이라는 함정. 받은 HTML은 '그림'일 뿐이라, JS가 붙기 전엔 버튼이 안 눌려요. 서버가 그린 것과 브라우저가 그릴 것이 어긋나면 hydration mismatch 경고가 나는데, 1인 개발자가 SSR에서 제일 자주 만나는 버그가 이거예요.

그 사이의 것들 — 사실 두 개가 아니다

SSR/CSR은 양 극단이고, 실무에서 많이 쓰는 건 그 사이 칸들이에요. 같은 "서버가 미리 그린다"도 언제 그리느냐로 갈립니다.

  • SSG (정적 생성) — 요청 때가 아니라 빌드 때 HTML을 다 만들어 CDN에 올려둬요. 내용이 자주 안 바뀌는 블로그·문서·랜딩에 최적. 서버가 요청마다 일하지 않아 가장 빠르고 가장 쌉니다. (이 블로그도 개념상 여기예요.)
  • ISR (증분 정적 재생성) — SSG인데 "N초마다 한 번씩 다시 만들기"를 붙인 것. 정적의 속도 + 가끔 갱신 둘 다 노릴 때.
  • RSC (React Server Components) — 컴포넌트 단위로 "이건 서버에서, 이건 브라우저에서"를 섞어요. 서버 컴포넌트는 JS 번들에 안 실려서 클라 번들이 가벼워집니다. Next.js App Router의 기본값이에요.

그래서 "Next.js = SSR"은 정확히는 틀렸어요. Next.js는 위 방식들을 페이지·컴포넌트마다 고를 수 있게 해주는 틀이지, 자동으로 전부 SSR이 되는 게 아닙니다.

비교 표

CSRSSRSSG(정적)
HTML 만드는 곳브라우저서버(요청마다)빌드 때 한 번
첫 화면 속도느림빠름가장 빠름
이후 이동매우 빠름빠름(하이드레이션 후)보통(부분 CSR화 가능)
SEO약함강함강함
서버 부담거의 없음요청마다 발생거의 없음
실시간/개인화강함강함약함(고정 콘텐츠)
운영 난이도낮음중~높음(hydration)낮음
전형적 예앱인토스 앱, 대시보드커머스 상세, 뉴스블로그, 문서, 랜딩
표를 한 문장으로: 검색·첫인상이 중요하면 서버가 미리 그리고(SSR/SSG), 로그인 뒤 개인화된 앱이면 브라우저가 그린다(CSR). 운영을 아끼고 싶으면 정적이 가장 편해요.

언제 뭘 쓰나

질문 몇 개만 따라가면 대부분 답이 나와요.

검색엔진 노출이 중요한 페이지인가? 아니오 CSR 앱인토스 · 대시보드 로그인 뒤 앱형 화면 내용이 사용자·요청마다 자주 바뀌나? 아니오 SSG (정적) 블로그 · 문서 · 랜딩 가장 빠르고 가장 쌈 가끔만 갱신해도 충분한가? ISR 정적 속도 + 주기 갱신 아니오 SSR 매 요청 최신 + 검색 노출 커머스 상세 · 뉴스
렌더링 방식 선택 흐름 — 검색 노출 → 변경 빈도 → 갱신 주기 순으로 따라가면 칸이 정해진다
  • 검색 노출 불필요 + 로그인 뒤 앱형 화면 → CSR
  • 검색 필요 + 내용 거의 안 바뀜 → SSG(정적)
  • 검색 필요 + 가끔 갱신이면 충분 → ISR
  • 검색 필요 + 매 요청 최신·개인화 필수 → SSR

그래서 나는 — 앱인토스는 CSR, 블로그는 정적

내가 운영하는 것들을 이 지도 위에 올려보면 답이 거의 자동으로 나와요.

  • 앱인토스 앱들 → 전부 CSR. 토스 앱 안의 웹뷰에서 도니까 구글 검색에 걸릴 일이 없어요. SEO가 필요 없으니 CSR의 유일한 약점이 사라집니다. 대신 로그인 뒤 탭을 옮겨 다니는 앱형 화면이라 CSR의 매끄러운 전환이 딱 맞고, 정적 파일만 올리면 돼서 운영 부담이 0이에요. 1인 개발자에게 이게 제일 큽니다.
  • 이 블로그 → 정적(SSG). 검색 유입이 생명인데 내용은 한번 쓰면 거의 안 바뀌어요. 요청마다 서버가 그릴 이유가 없으니 빌드 때 만들어 CDN에 얹는 게 가장 빠르고 가장 쌉니다.
  • 고양이 타로 앱 → 서버를 아예 뺐죠. 지난 글에서 Edge Function으로 옮긴 그 결정도 결국 같은 사고예요. "이 화면이 서버 렌더링을 요구하는가?"를 먼저 묻고, 아니면 서버를 안 두는 쪽으로.

요점은 "SSR이 더 고급이라서 써야 한다"가 아니라, 내 화면이 서버 렌더링을 요구하느냐예요. 앱인토스 앱에 굳이 SSR을 얹었다면 서버 비용과 하이드레이션 버그만 떠안고 얻는 건 없었을 거예요.


마무리: 렌더링 위치는 도구지 목표가 아니다

"Next.js 쓰면 SSR 아니에요?"에 대한 가장 정직한 답은 "Next.js는 어디서 그릴지 고를 수 있게 해주는 틀일 뿐, 내 페이지가 그걸 요구해야 SSR을 쓴다"예요. 제일 흔한 실수는 제일 있어 보이는 방식을 먼저 고르고 거기에 화면을 끼워 맞추는 거더라고요.

순서는 반대여야 합니다. 먼저 묻기 — 이 화면이 검색에 걸려야 하나? 그다음 — 내용이 요청마다 바뀌나, 운영은 누가 감당하나? 이 두 질문이면 CSR · SSR · SSG · ISR 중 어디로 갈지 거의 정해져요. 프레임워크 선택은 그다음입니다.

728x90