FrontEnd/React

React에서 CRA보다 Vite가 좋다고? - Vite를 사용하는 이유

Grace 2022. 12. 19. 22:14

이런 문제점이 있었어요

브라우저에서 ESM을 지원하기 전까지는, 자바스크립트 모듈화를 네이티브 레벨에서 진행할 수 없었습니다. 따라서 개발자들은 번들링이라는 우회적인 방법을 사용했습니다(Webpack 같은).

하지만 애플리케이션이 점점 더 발전함에 따라 처리해야 하는 자바스크립트 모듈의 개수도 극적으로 증가하고 있습니다. 심지어 대규모 프로젝트에서는 수천 개의 모듈이 존재합니다. 이러한 상황에서 자바스크립트 기반의 도구는 성능 병목 현상이 발생되었고, 종종 개발 서버를 가동하는 데 비합리적으로 오랜 시간을 기다려야 한다거나 HMR을 사용하더라도 변경된 파일이 적용될 때까지 수 초 이상 소요되곤 했습니다. 이와 같은 느린 피드백 루프는 개발자의 생산성에 큰 영향을 줄 수 있습니다.

💡HMR
브라우저를 새로 고치지 않아도 웹팩으로 빌드한 결과물이 웹 애플리케이션에 실시간으로 반영될 수 있게 도와주는 설정입니다. 브라우저 새로 고침을 위한 LiveReload 대신에 사용할 수 있으며 웹팩 데브 서버와 함께 사용할 수도 있습니다.

Vite는 이러한 것에 초점을 맞춰, 브라우저에서 지원하는 ESM 및 네이티브 언어로 작성된 자바스크립트 도구 등을 활용해 문제를 해결하고자 합니다.

지루할 정도로 길었던 서버 구동

콜드-스타트(최초로 실행되어 이전에 캐싱한 데이터가 없는 경우) 방식으로 개발 서버를 구동할 때, 번들러 기반의 도구의 경우 애플리케이션 내 모든 소스 코드에 대해 크롤링 및 빌드 작업을 마쳐야지만 실제 페이지를 제공할 수 있습니다.

vite는 이 문제를 dependencies 그리고 source code 두 가지 카테고리로 나누어 개발 서버를 시작하도록 함으로써 해결했습니다.

  • dependencies: 개발 시 그 내용이 바뀌지 않을 일반적인 자바스크립트 소스 코드입니다. 기존 번들러로는 컴포넌트 라이브러리와 같이 몇 백 개의 자바스크립트 모듈을 갖고 있는 매우 큰 디펜던시에 대한 번들링 과정이 매우 비효율적이였고 많은 시간을 필요로 했습니다. Vite의 사전 번들링 기능은 Esbuild를 사용하고 있습니다. Go로 작성된 Esbuild는 Webpack, parcel과 같은 기존 번들러 대비 10-100배 빠른 번들링 속도를 보입니다.
  • Source code: JSX, CSS 또는 Vue/Svelt 컴포넌트와 같이 컴파일링이 계속 필요하고, 수정 또한 매우 잦은 Non-plain 자바스크립트 소스 코드는 Native ESM을 이용해 소스 코드를 제공하도록 하고 있습니다. 브라우저가 곧 번들러라는 말입니다. 브라우저의 판단 아래 특정 모듈에 대한 소스 코드를 요청하면 이를 vite가 전달합니다. 따라서 조건부 동적 import 이후의 코드는 현재 와면에서 실제로 사용이 되어야만 처리가 됩니다.

느렸던 소스 코드 갱신

기존의 번들러 기반으로 개발을 진행할 떄, 소스 코드를 업데이트 하게 되면 번들링 과정을 다시 거쳐야 했습니다. 따라서 서비스가 커질수록 소스 코드 갱신 시간 또한 선형적으로 증가할 수 밖에 없었습니다.

일부 번들러의 경우 메모리 상에서 이를 진행하여 실제로 갱신에 영향을 받는 파일들만 새롭게 번들링하게끔 했지만, 결국 이 역시 처음에는 모든 파일을 번들링 해야 했습니다. "모든 파일"을 번들링 하고, 이를 다시 웹 페이지로 불러오는 비효율적인 이슈를 우회하고자 HMR이라는 대안이 나왔지만, 이 역시 명확한 해답은 아니었습니다.

vite 역시 HMR을 지원하지만, 번들러가 아닌 ESM을 이용해서 지원합니다. 어떤 모듈이 수정되면 vite는 수정된 모듈과 관련된 부분만을 교체하며, 브라우저에서 해당 모듈을 요청하면 교체된 모듈로 전달합니다. 전 과정에서 완벽하게 ESM을 사용하기에, 앱 사이즈가 커져도 HMR을 포함한 갱신 시간에는 영향을 끼치지 않습니다.

또한 vite는 HTTP 헤더를 이용해 퍼포먼스를 한 단계 높였습니다. 필요에 따라 소스 코드는 304 Not Modified, 디펜던시는 Cache-Control: max-age=31536000,immutable을 이용해 캐시되도록 함으로써 한 번의 요청이라도 덜하도록 합니다.

배포 시 번들링 과정이 필요한 이유

기본적으로 ESM이 대부분의 환경에서 지원되지만, 프로덕션에서 번들 되지 않은 ESM을 가져오는 것은 중첩된 import로 인한 추가 네트워크 통신으로 인해 비효율적입니다. 프로덕션 환경에서 최적으로 로딩 성능을 얻으려면 트리 셰이킹, 지연 로딩 및 청크 파일 분할을 이용하여 번들링 하는 것이 좋습니다.

개발 서버와 프로덕션 빌드 간에 최적의 출력과 동작 일관성을 보장하는 것은 쉽지 않습니다. 이것이 바로 Vite가 미리 설정된 빌드 커맨드를 이용하고, 빌드 퍼포먼스 최적화를 진행하는 이유입니다.

왜 번들링 시에는 Esbuild를 사용하지 않나요?

Esbuild는 극단적으로 빠른 속도로 번들링이 가능하다는 장점이 있지만, 번들링에 필수적으로 요구되는 기능인 코드 분할 및 CSS와 관련된 처리가 미비합니다. Vite에서 사용중인 Rollup은 이에 대해 조금 더 검증되었고 유연한 처리가 가능하게끔 구현되어 있기에 현재는 이를 사용하고 있으며, 향후 Esbuild가 안정화 되었을 때 어떤 프로덕션 번들링 도구가 적절한지 다시 논의할 예정입니다.