Develope/React

CRA에서 Vite + SSR로 마이그레이션하며 겪은 문제와 해결 과정

oper0116 2026. 4. 5. 20:48
반응형

1. 문제 상황

기존 서비스는 CRA(Create React App) 기반의 CSR 구조로 운영되고 있었다.
초기에는 빠른 개발과 단순한 구조 덕분에 큰 문제가 없었지만, 서비스가 성장하면서 점점 한계가 드러났다.

특히 다음과 같은 문제가 반복적으로 발생했다.

  • 초기 로딩 속도 지연 (FCP/LCP 저하)
  • SEO 대응의 어려움
  • 번들 사이즈 증가
  • Webpack 기반 빌드 속도 저하

단순한 최적화로는 해결이 어려웠고,
결국 렌더링 방식 자체를 바꾸는 방향을 검토하게 되었다.


2. 기존 구조의 한계

2.1 CSR 구조의 구조적 문제

CRA 기반 CSR에서는 모든 렌더링이 클라이언트에서 이루어진다.

이로 인해:

  • HTML은 비어있는 상태로 전달됨
  • JS 로딩 이후에야 화면 렌더링
  • 초기 사용자 경험 저하

특히 네트워크 환경이 좋지 않을수록 문제는 더 크게 체감되었다.


2.2 Webpack 기반 개발 경험의 한계

프로젝트 규모가 커지면서 개발 환경에서도 문제가 발생했다:

  • 개발 서버 시작 속도 저하
  • HMR 속도 저하
  • 빌드 시간 증가

개발 생산성 자체가 점점 떨어지는 상황이었다.


3. 해결 방향

다음 두 가지를 핵심 목표로 설정했다:

  1. 초기 렌더링 성능 개선 → SSR 도입
  2. 개발 경험 개선 → Vite 도입

4. Vite + SSR 선택 이유

4.1 Vite

  • 빠른 개발 서버 시작
  • 즉각적인 HMR
  • ES Module 기반 구조

→ 개발 경험이 크게 개선됨


4.2 SSR

  • 초기 HTML에 콘텐츠 포함
  • 빠른 첫 렌더링
  • SEO 대응 가능

→ 사용자 체감 성능 개선


5. 마이그레이션 과정

5.1 구조 변경

기존:

  • CRA (CSR)

변경:

  • Vite (빌드/개발 환경)
  • Node.js 기반 SSR 서버

5.2 라우팅 처리

  • 서버에서 route 매칭
  • 초기 데이터 fetch
  • HTML에 상태 주입

5.3 상태 동기화

  • 서버에서 데이터 fetch
  • serialize → HTML에 포함
  • 클라이언트에서 hydrate

5.4 Hydration 이슈

SSR 도입 시 가장 많이 겪는 문제:

원인

  • 서버/클라이언트 렌더링 결과 불일치
  • 브라우저 전용 API 사용

해결

  • useEffect로 클라이언트 로직 분리
  • 조건부 렌더링
  • 랜덤/시간 기반 값 제거

6. 성능 개선 결과

  • 초기 렌더링 속도 개선
  • 체감 성능 향상
  • SEO 대응 가능

특히 “빈 화면 → 렌더링” 구조가 사라진 것이 가장 큰 변화였다.


7. 트러블 슈팅: Event Loop Lag 문제

SSR 도입 이후 또 다른 문제가 발생했다.
바로 Node.js Event Loop Lag 증가였다.


7.1 문제 현상

  • API 응답 속도 지연
  • 서버 CPU 사용량 증가
  • SSR 렌더링 시간 불안정

특히 트래픽이 몰리는 구간에서 심각하게 나타났다.


7.2 원인

SSR에서는 요청마다 서버에서 렌더링이 수행된다.

이 과정에서:

  • React 렌더링 (renderToString)
  • 데이터 가공 로직
  • 동기 처리

CPU 바운드 작업이 Event Loop를 점유


7.3 문제의 본질

Node.js는 싱글 스레드 기반이기 때문에
하나의 요청이 오래 걸리면 전체 처리에 영향을 준다.

SSR 환경에서는 이 문제가 더 쉽게 드러난다.


7.4 해결 방법

1. 렌더링 최적화

  • 불필요한 렌더링 제거
  • 메모이제이션 적용

2. 데이터 처리 분리

  • SSR에서는 최소 데이터만 사용
  • 무거운 로직은 별도 처리

3. 캐싱 도입

  • SSR 결과 캐싱
  • 데이터 캐싱

4. 비동기 처리 개선

  • 동기 로직 제거
  • 비동기 처리로 전환

7.5 개선 결과

  • Event Loop Lag 감소
  • 응답 속도 안정화
  • 트래픽 상황에서도 성능 유지

8. 느낀 점

  • 성능 문제는 단순 최적화로 해결되지 않는다
  • 렌더링 방식 변경이 더 효과적인 경우가 많다
  • SSR은 강력하지만 복잡도를 증가시킨다
  • Node.js 환경에서는 Event Loop 이해가 필수다

9. 이런 경우에 추천

  • 초기 렌더링 성능이 중요한 서비스
  • SEO가 필요한 서비스
  • CRA 기반에서 한계를 느끼는 경우

10. 마무리

CRA에서 Vite + SSR로의 전환은
단순한 도구 변경이 아니라
애플리케이션 구조 자체를 재설계하는 작업이었다.

초기 비용은 있지만,
장기적으로는 충분한 가치가 있다고 판단된다.


반응형