본문으로 건너뛰기

"CRA" 태그로 연결된 2개 게시물개의 게시물이 있습니다.

모든 태그 보기

빌드시간 개선을 위한 CRA to Vite Migration

· 약 4분

현재 CRA를 기반으로 만들어진 패키지로 웹뷰 서비스를 배포하고 있는데요. 기존까지는 큰 문제가 없었지만, 클라우드 서버 내에서 빌드를 하게 되면서 빌드시간이 2~3배 증가하는 문제가 생겼습니다. 때문에 빌드시간 단축을 위해 CRA의 Webpack v5에서 Vite 로 Migration을 시도했는데요. CRA에서 Vite로 변경했을 때의 빌드시간과 함께 이때 발생한 문제점에 대해 공유드리려 합니다.

왜 Vite를 사용하나요? Vite는 사전빌드를 거친 후 Native ESM을 사용하여 배포하는데, 개발단계에서는 Go로 작성된 Esbuild를 사용해서 Webpack, Parcel과 같은 기존의 번들러 대비 10-100배 빠른 속도를 제공합니다. 다만, 확장성과 안정성을 위해 배포시에는 Rollup을 기반으로한 사전 빌드를 거칩니다. ⠀ CommonJS를 통하여 빌드할 뿐만 아니라 필요하지 않은 설정까지 포함된 CRA에 비해 Vite는 더 가볍고 빠르기 때문에 최근 CRA보다 Vite를 사용하는 추세입니다.


Vite를 사용하여 빌드한 결과

기존 CRA의 환경변수와 플러그인을 Vite로 변경하고, Vite Migration을 위해 몇가지 수정을 거친 후 테스트를 진행하였습니다.

그 결과 꽤 극적인 결과가 나타났습니다.

  • 기존 CRA의 Webpack을 사용한 빌드시간
    • 1 min 35 sec total from scheduled to completion.
  • Vite 변경 후 빌드시간 (기존 대비 약 67% 빠름) - 31 sec total from scheduled to completion. ⠀
  • 기존 CRA의 Webpack을 사용한 클라우드 서버 빌드시간
    • 4 min 8 sec total from scheduled to completion.
  • Vite 변경 후 클라우드 서버 빌드시간 (기존 대비 약 57% 빠름)
    • 1 min 47 sec total from scheduled to completion.

구형 브라우저 지원이 필수적인 웹뷰 환경

그러나 여기에는 한가지 간과한 부분이 있었습니다. Vite v5는 네이티브 ES 모듈네이티브 ESM의 동적 Import, 그리고 import.meta 을 지원하는 브라우저를 타깃으로 하고 있습니다. (Vite 브라우저 지원 현황)

하지만 웹뷰 특성상 여러 기기에서 사용하기 때문에 오래된 브라우저에 대한 지원이 필수적입니다. 실제로 간혹 Object.fromEntries 와 css gap 속성을 사용하지 못하는 기기로 인해 문제가 생기기도 했습니다.

때문에 @vitejs/plugin-legacy 를 사용하여 오래된 브라우저를 위해 폴리필 해줘야만 하는데요. last 2 versions and not dead, > 0.3% 으로 폴리필 한 결과 다음과 같은 결과가 나타났습니다.

  • Vite 구형 브라우저 폴리필 지원 후 빌드시간 (기존 대비 약 24% 빠름)
    • 1 min 12 sec total from scheduled to completion.
  • Vite 구형 브라우저 폴리필 지원 후 클라우드 서버 빌드시간 (기존 대비 약 79% 느림)
    • 7 min 24 sec total from scheduled to completion.

클라우드 서버에서 좋지 않은 결과를 보여주는 이유는?

Native ESM를 사용하는 Vite와는 달리, CRA의 Webpack은 CommonJS를 사용하고 있기 때문에 구형 브라우저에 대한 지원율이 높습니다. 하지만 Vite의 경우 더 많은 폴리필을 지원해야 하기 때문에 같은 커버리지를 지원하면서도 상대적으로 빌드 시간이 더 오래 걸리게 되는 것인데요.

그럼에도 로컬 빌드 시 조금 더 빠른 성능을 보여주는 이유는 Vite의 배포 빌드 시 사용하는 Rollup은 Rust로 쓰여진 SWC를 파서로 사용하고 있기 때문에(https://github.com/rollup/rollup/pull/5073)  성능이 좋은 멀티코어 환경에서는 조금 더 빠른 성능을 보여주지만, 성능이 좋지않은 클라우드 서버 환경에서는 매우 느린 결과를 보여주고 있다고 추측합니다.


결론

구형 브라우저까지 지원할 필요가 없는 환경이거나,  멀티코어 성능이 좋은 환경에서 빌드를 해야 한다면 Vite는 좋은 선택이 될 것 입니다. 다만 웹뷰와 같이 많은 사용자에 대한 지원이 필요한 환경이라면 빌드속도를 위해 Vite를 선택하는 것은 그리 효과적이지 않을 수 있습니다.

Vite에 대한 간단한 소개::CRA 대신 Vite를 사용해보는 것은 어떤가요?

· 약 3분

Vite 개요

빠르다는 의미의 프랑스어 vite는 바이트가 아닌 비트라고 읽는다. 이름과 같이 vite는 매우 빠른 속도를 보여주는데, Vite의 사전 번들링 기능은 Go 언어로 작성된 Esbuild을 사용하여 기존 Webpack, Parcel과 같은 번들러 대비 10-100배 빠른 속도를 가진다.


Vite가 생겨나게 된 배경

vite를 비롯하여 이렇게 빠른 속도를 가진 도구들이 출시될 수 있는 배경에는 메이저 브라우저 엔진들이 네이티브 자바스크립트 모듈을 지원하기 시작하면서이다.

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

때문에 개발 서버를 실행할 때 오랜 시간이 걸릴 수 있으며, 편집한 코드가 브라우저에 반영되기 까지 수 초 이상의 시간이 소요되기도 했다.


Vite는 어떻게 빠른 속도를 가질 수 있는가?

vite는 이를 해결하기 위해 내용이 바뀌지 않을 Plain JavaScript 소스 코드를 Go로 작성된 Esbuild를 사용하여 사전번들링하고, JSX, CSS와 같이 컴파일이 필요하고 수정이 잦은 Non-plain JavaScript 소스 코드에 대해서는 Native ESM을 이용하여 코드를 편집하자마자 브라우저가 변경될 수 있도록 만들었다. (하지만 사전번들링 시 Esbuild는 아직 불안정하기 때문에 Rollup을 사용하고 있다.)

Native ESM은 소스코드를 제공하는 방식을 사용하는데, 개발 서버를 구동할 때, 애플리케이션 내 모든 소스 코드에 대해 크롤링 및 빌드 작업을 마쳐야지만이 실제 페이지를 제공할 수 있었던 번들러 기반의 도구와 달리, 브라우저가 삽입 구문을 찾고 HTTP로 해당 모듈을 요청하고, 요청된 모듈과 모듈의 가져오기 트리에 있는 모든 잎 노드에 변환을 적용한 다음 이를 브라우저에 제공하는 방식이다.


그렇다면 Vite에는 장점만 있는 것일까?

일반적으로 자주 사용하는 번들러인 CRA의 경우, jest, svg-loader 등이 기본적으로 설치되어 있으며 eslint, prettier 등을 바로 설치해서 사용할 수 있다.

하지만 Vite의 경우 jest, svg-loader 등을 하나하나 설치해줘야 하며 eslint, prettier, favicon 등을 사용할 때 플러그인을 별도로 설치해줘야 한다.

하지만 웹팩에 추가 설정을 하기 위해 craco와 같은 라이브러리로 조작해야하는 CRA에 비해 자체적으로 config를 수정할 수 있도록 지원하여 손쉬운 절대경로 설정이 가능하며 CRA의 대부분의 기능을 대체할 수 있으므로, 다음 프로젝트를 기획하고 있다면 CRA 대신 Vite를 사용해보는 것을 적극 권장한다.



참고자료:

vitejs-kr, TOAST UI https://wonillism.tistory.com/271