mason
mason-log.

GitHub 로그인 중

렌더링 타입 (CSR, SSR, SSG, ISR).
mason

masonfe-hyunsu

🧭 1. 개요.

  • CSR, SSR, SSG, ISR는 화면 HTML을 언제, 어디서 만드느냐로 나눈 렌더링 타입이다.

  • 페이지마다 화면을 어떻게 그릴지 고를 때도, 이 네 축으로 방향성을 잡게 된다.

  • 이 포스팅에서는 각 타입이 어떻게 동작하는지, 어떤 페이지에 잘 맞는지 정리해 본다.

한 줄로 보면 이렇다.

  • CSR: 브라우저에서 그린다

  • SSR: 요청올 때 서버에서 그린다

  • SSG: 빌드할 때 미리 그린다

  • ISR: 미리 그리되, 필요할 때 다시 그린다

렌더링 네 타입 한눈에
  • 왼쪽부터 CSR → SSR → SSG → ISR 순서다. 자세한 설명은 아래부터.


🖥️ 2. CSR : 브라우저에서 그리기.

  • CSR (Client-Side Rendering)은 JS를 받은 뒤, 브라우저에서 HTML을 만드는 방식이다.

  • Create React App으로 SPA를 만들던 시절이 딱 이 그림이었다.

요청 → 거의 빈 HTML + JS
→ 브라우저가 JS 실행
→ 데이터 fetch
→ 화면 완성
  • 로그인 후 대시보드처럼 검색 노출이 크게 중요하지 않은 화면, 들어온 뒤 오래 붙잡고 쓰는 앱에는 잘 맞았다.

  • 대신 첫 화면이 느리게 느껴질 때가 많다. JS를 받고, 돌리고, fetch가 끝나야 본문이 보이기 때문이다.

  • 링크 미리보기나 크롤러도 빈 HTML만 볼 위험이 있어서, 요즘은 진입만 서버/정적으로 두고 안쪽은 CSR로 가는 식이 더 흔하다.

첫 화면 체감만 잘라 보면 대략 아래 느낌이다.

  • 왼쪽: 빈 화면(로딩) 뒤에 내용이 채워지는 CSR 쪽

  • 오른쪽: HTML 내용이 먼저 내려오는 SSR 쪽

CSR과 SSR 첫 화면 체감

🖨️ 3. SSR : 요청마다 서버에서 그리기.

  • SSR (Server-Side Rendering)은 요청이 올 때마다 서버가 HTML을 만들어 내려준다.

  • 브라우저는 그 HTML을 먼저 보여 주고, 이후 JS로 클릭, 입력 같은 걸 붙인다. 이 붙이는 과정이 Hydration이다.

요청 → 서버에서 데이터 조회 + HTML 생성
→ HTML 응답
→ JS 로드 후 hydrate
→ 상호작용 가능
  • 검색, OG 이미지가 중요한 페이지나, 로그인 사용자마다 내용이 달라져야 하는 화면에서 자주 골랐다.

  • 다만 매 요청마다 서버 일이 생긴다. TTFB가 길어질 수 있고, 트래픽이 늘면 서버도 같이 바빠진다.

  • Next.js에서는 getServerSideProps 때부터 익숙했고, App Router의 동적 렌더링도 같은 축으로 보면 편했다.

  • HTML과 클라이언트 렌더 결과가 어긋나면 hydration mismatch가 난다. 서버에서 그린다와 브라우저에서 살아 움직인다를 구분해 두면 이런 이슈도 덜 막막하다.


📦 4. SSG : 빌드할 때 미리 그리기.

  • SSG (Static Site Generation)은 빌드 시점에 HTML을 만들어 두고, CDN이나 정적 호스팅으로 뿌린다.

  • 이 블로그처럼 글이 자주 안 바뀌는 콘텐츠랑은 거의 정석이다.

빌드 → 페이지 HTML 생성
→ S3 + CloudFront 같은 곳에 배포
→ 요청 시 캐시된 HTML 응답
  • 문서, 랜딩, 마케팅 페이지처럼 배포 시점에 내용이 확정되는 곳에 잘 맞는다.

  • 대신 내용을 바꾸려면 다시 빌드해야 하고, 페이지가 아주 많으면 빌드 자체가 길어진다.

  • output: "export"로 정적 파일을 뽑는 경우도 이 계열로 보면 된다.


♻️ 5. ISR : 미리 그리되, 가끔 다시 그리기.

  • ISR (Incremental Static Regeneration)은 SSG처럼 미리 만들되, 시간이 지나면 백그라운드에서 다시 굽는 방식이다.

  • 완전 정적과 매 요청 SSR 사이에서 타협한 느낌이다.

빌드 → 정적 HTML
→ 캐시로 제공
→ revalidate 시간이 지나면
→ 다음 요청 이후 백그라운드 재생성
→ 이후 요청부터 새 HTML

그림으로만 보면 대략 이 루프다.

    ISR 재생성 루프
  • 박스: 빌드 (미리 만들기)

  • 구름: 캐시에 올려 두기

  • 회전 화살표: 필요할 때 다시 굽기

  • 상품 목록이나 뉴스처럼, 자주 바뀌진 않는데 배포마다 전부 다시 빌드하기엔 무거운 페이지에서 손이 갔다.

  • CDN 속도는 유지하면서 내용을 주기적으로 갱신하고 싶을 때 유용하다.

  • 다만 잠깐 옛 내용이 보이는 stale 구간이 생길 수 있고, revalidate나 on-demand 재생성을 같이 설계해야 한다. 여기부터는 캐시 감각이 좀 필요하다.


🎯 6. 고를 때 보는 기준.

렌더링 타입 선택 기준

페이지 전략을 고를 때는 이런 질문을 먼저 본다.

  • 이 페이지는 검색, 공유가 중요한가?

  • 데이터가 요청마다 달라져야 하나, 빌드 시점이면 되나?

  • 갱신은 분 단위인가, 하루 단위인가, 배포 때만인가?

  • 서버를 그만큼 돌려도 되나?

감으로 정리하면 대략 이렇다.

  • 로그인 후 앱 화면 → CSR (또는 혼합)

  • 개인화된 HTML이 당장 필요 → SSR

  • 거의 안 바뀌는 문서, 블로그 → SSG

  • 정적 속도는 유지하고 가끔만 갱신 → ISR

한 사이트 전체를 한 방식으로 묶기보다, 페이지마다 다르게 고르는 편이 맞았다. "우리 서비스는 SSR이다"보다 "이 페이지는 왜 SSR인가"가 더 쓸모 있었다.


💡 7. 정리.

  • CSR: 브라우저에서 HTML 구성

  • SSR: 요청마다 서버에서 HTML 구성

  • SSG: 빌드 때 HTML 구성

  • ISR: SSG + 필요할 때 재생성


🔗 8. 참고 자료.

이전 글
블로그 리리뉴얼.

댓글

불러오는 중...
목록으로