Last edited: March 29, 2026
프로젝트 투입 후, 32만줄 규모의 레거시 React 프로젝트에서 로컬 개발 서버 시작에 4~5분, HMR이 사실상 작동하지 않는 문제를 겪었다. Vite로 번들러를 교체하니 체감 속도가 극적으로 개선됐는데, "왜 빨라지는가"를 감이 아닌 구조적 근거로 설명하고 싶었다.
Webpack 4는 Bundle-based Dev Server다. 개발 서버를 띄우려면 전체 소스코드를 파싱하고, 의존성 그래프를 구축하고, 번들을 생성한 뒤에야 브라우저에서 접근할 수 있다.
추가로 발견한 번들 비효율:
| 문제 | 영향 |
|---|---|
| moment.js 137개 locale 전부 포함 | IgnorePlugin 미설정, 불필요한 5.2MB |
| lodash 전체 import | tree-shaking 플러그인 없음, 4.9MB |
| core-js 풀 폴리필 | 현대 브라우저 타겟인데 14MB 폴리필 |
| 4중 폴리필 중복 | core-js + regenerator + react-app-polyfill + event-source-polyfill |
정확한 원인 파악에 실패했다. 추정되는 원인들:
react-app-rewired로 CRA 내부 설정을 monkey-patch하면서 HMR 클라이언트 주입 타이밍이 꼬일 수 있다.useState가 29개인 파일에서는 React Fast Refresh가 state 보존을 포기한다.[Webpack 4 — Bundle-based]
시작 → 전체 파일 파싱 → 의존성 그래프 구축 → 번들 생성 → Dev Server 시작
⏱️ 32만줄 전부 처리 후에야 브라우저 접근 가능
[Vite — Native ESM]
시작 → esbuild로 deps만 pre-bundle → Dev Server 즉시 시작
→ 브라우저가 요청하는 모듈만 on-demand 변환
⏱️ 요청된 파일만 처리
핵심은 브라우저가 번들러의 역할을 일부 대신한다는 점이다.
이 프로젝트에서 차이가 극적인 이유:
[Webpack 4] 파일 변경 → 관련 청크 전체 리빌드 → 번들 교체
[Vite] 파일 변경 → 해당 모듈 1개만 ESM 교체 → 브라우저가 해당 모듈만 re-fetch
react-app-rewired + customize-cra의 monkey-patch가 vite.config.js 하나로 대체