
개인 블로그 프로젝트를 개발하면서 Next.js의 SSR(Server Side Rendering) 구조를 도입했다. React Query와 Zustand를 활용해 클라이언트 상태도 정교하게 관리하고, 렌더링 성능과 사용자 경험도 신경 써가며 꽤나 복잡한 구조를 완성했다.
하지만 실제 운영을 시작하고 나서, 몇 가지 현실적인 문제에 직면하게 됐다. 이 글은 현재의 SSR 구조가 어떤 식으로 동작하고 있는지, 그리고 왜 SSG(Static Site Generation) 기반으로 전환하려고 결심하게 되었는지에 대한 기술적 이유와 개인적인 판단을 정리한 기록이다.
✅ 현재 SSR 기반 구조 분석
전체 구조 개요
Next.js App Router 기반 SSR
React Query로 서버-클라이언트 간 상태 동기화
Zustand로 인증 상태 전역 관리
Posts, Projects 등 주요 페이지는 서버에서 데이터 프리페치 후
dehydrate()
로 직렬화
<Suspense fallback={<BlogListSkeleton />}> {children} </Suspense>
렌더링 흐름
서버
API 호출로 초기 데이터 확보
dehydrate
로 React Query 상태 직렬화
클라이언트
HydrationBoundary
로 Query 상태 복원CSR 컴포넌트에서 인터랙션 처리
클라이언트 분기 예시
경로 | 서버 렌더링 데이터 | 클라이언트 컴포넌트 |
---|---|---|
| 게시글 목록, 태그 목록 | PostsPageClient |
| 태그 필터링된 포스트 | PostsPageClient |
| 프로젝트 리스트 | ProjectsPageClient |
이 구조는 기술적으로 매끄럽고, 실시간 동기화가 필요한 서비스에는 적합하다. 하지만, 블로그라는 정적 콘텐츠 중심 서비스에선 과한 설계일 수 있다.
❗ SSR 구조가 부담이 되는 이유
제한된 무료 서버 환경
Render 무료 플랜
512MB RAM / 0.1vCPU
2명 접속 시에도 네트워크 사용량 3MB 초과
이와 별개로, 무료 플랜에서는 ram과 cpu의 현재 사용현황을 확인할 수 없다는 점도 부담의 요소로 다가왔다.
SSR은 요청마다 다음을 반복:
React 렌더링
API 호출
상태 직렬화
글 수나 방문자 수가 늘면 리소스 소비가 기하급수적으로 증가함
과도한 API 호출
/posts?tag=...
요청마다 서버는 매번 DB에서 필터링된 결과를 가져옴실제로는 정적인 데이터인데, 매번 API 호출이 발생함
인증과 초기화 상태 동기화 부담
클라이언트 상태(Zustand)와 서버 상태(React Query)를 모두 동기화
하이드레이션 로직은 SSR의 복잡도를 높이고 리소스를 더 많이 요구함
🚀 그래서, 왜 SSG인가?
SSG의 이점
항목 | 장점 |
---|---|
정적 콘텐츠 | 글은 자주 안 바뀜 → 정적 HTML이 적합 |
빠른 응답속도 | HTML을 CDN에 캐싱 → 즉시 응답 가능 |
서버 부하 없음 | 요청 시 API 호출이나 상태 직렬화 필요 없음 |
비용 효율성 | 서버 없이 운영 가능 (Vercel, S3 등) |
블로그 도메인과의 적합성
블로그는 대부분의 콘텐츠가 정적이고, 글 조회가 중심이다. 최신성을 유지해야 할 이유도 적고, 실시간 반응보다 빠른 로딩 속도와 가벼운 운영비용이 더 중요하다.
🔄 구조 전환 전략: SSG + CSR 분리
현재 구조에서 완전히 전환하기보다는, 기능 단위로 SSR과 CSR을 명확히 분리한 구조를 고민 중이다.
기능별 판단
기능 | 방식 | 이유 |
---|---|---|
글/프로젝트 조회 | SSG | 정적 콘텐츠, 잦은 변경 없음, SEO 중요 |
태그별 필터링 | SSG + | 태그 목록을 기준으로 정적 경로 생성 |
글 작성/수정 | ISR ( | 관리자(나만) 전용, 로그인 필요, 실시간성 필요 없음 |
인증 상태 | CSR (Zustand, 쿠키, etc) | Zustand를 통한 클라이언트 인증 상태 관리로 충분 |
🤔 되돌아보면, 너무 복잡하게 시작했다
개발 초기에 "풀스택을 기반으로하는 서비스 개발을 해보자"는 식의 막연한 흥미 위주로 구조를 설계했다.하지만 지금 와서 보니, 이 프로젝트는 Supabase 같은 BaaS + SSG 구조로도 훨씬 간단하게 만들 수 있었을 것이다.
Supabase → DB + 인증 + API 제공
Next.js SSG + ISR로 콘텐츠는 정적으로 처리
이 조합만으로도 충분히 동작하는 블로그를 만들 수 있었고, 프로젝트 구조에 대한 걱정도 덜었을 것이다.
😌 하지만 후회보다는 확장성
지금 구조는 분명 과하긴 했지만, 덕분에 다음과 같은 확장 가능성을 얻었다.
직접 백엔드를 운영하면서 데이터를 자유롭게 설계할 수 있음
블로그를 단순한 글 저장소를 넘어서 지식 관계형 구조로 확장 가능
SSR, CSR, SSG의 차이를 실제로 체감하고 구조적 결정을 할 수 있는 실전 경험
🧩 결론
서비스의 특성에 따라 기술 스택을 결정하자. 렌더링 방식도 마찬가지.무리한 실시간 처리보다는 정적 구조 + 선택적 동적 기능 조합이 훨씬 실용적이고 효율적이다.
앞으로는 SSG를 기반으로 하되, 필요한 기능에 한해서만 CSR을 도입하고, 가능한 정적 구조에 적합한 설계를 유지하려고 한다.
이 글이 비슷한 고민을 하고 있는 개발자들에게 현실적인 참고가 되었으면 한다.