본문 바로가기

JavaScript

4 Reasons Why You Should Prefer Vite Over Create-React-App

아래 글을 번역한 것입니다. 

 

 

4 Reasons Why You Should Prefer Vite Over Create-React-App (CRA) - Semaphore

Unlike CRA, Vite does not build your entire application before serving, instead, it builds the application on demand. It also leverages the power of native ES modules, esbuild, and Rollup to improve development and build time.

semaphoreci.com

 

CRA는 대부분의 개발자가 리액트 프로젝트를 scaffold하고 개발 서버를 설정하는데 사용해온 도구입니다. 별도의 설정 없이 최신 빌드 설정을 제공합니다.

 

하지만 프로젝트의 규모가 커지면 개발 및 빌드 시간이 늘어납니다. 이렇게 느린 피드백 루프는 개발자의 생산성과 행복도에 영향을 미칩니다.

 

이러한 문제를 해결하기 위해 프론트엔드 생태계에 새로운 도구가 도입되었습니다. Vite.

CRA와 달리 Vite는 서비스하기 전에 전체 애플리케이션을 빌드하는 것이 아니라 온디맨드 방식으로 애플리케이션을 빌드합니다. 또한 네이티브 ES 모듈, esbuild 및 롤업의 기능을 활용하여 개발 및 빌드 시간을 개선합니다. 

 

Why is CRA slow?

CRA는 내부적으로 웹팩을 사용합니다. 웹팩은 전체 애플리케이션 코드를 번들로 묶은 후 서비스합니다. 코드베이스가 크면 개발 서버를 가동하는데 더 많은 시간이 걸리고 변경 사항을 반영하는데 시간이 오래 걸립니다. 

 

아래 다이어그램은 번들 기반 개발 서버를 시작하기 위해 모든 코드를 번들로 묶어야 하는것을 보여줍니다.

 

What is Vite?

Vite는 속도와 성능에 중점을 둔 차세대 프런트엔드 도구입니다. Vite는 크게 두 부분으로 구성됩니다.

 

1. Native ES Module에 비해 다양한 기능을 제공하는 개발 서버: HMR, pre-bundling, 타입스크립트 지원, JSX 및 dynamic import 지원

2. 프로덕션에 최적화된 정적 에셋을 출력하도록 사전 구성된 롤업과 함께 코드를 번들로 제공하는 빌드 명령

 

Why Prefer Vite over create-react-app?

1. Faster spin-up of the development server

 

CRA 또는 번들러 기반 빌드 설정과 달리 Vite는 서비스하기 전에 전체 애플리케이션을 빌드하지 않습니다. 애플리케이션 모듈을 종속성과 소스코드의 두 가지 범주로 나눕니다.

 

1. Dependencies are plain JavaScript that do not change often during development(large component libraries like mui).

 

- Vite pre-bundles these dependencies using esbuild, which is 10 ~ 100x faster than JavaScript-based bundlers.

- Pre-bundling ensures that each dependency maps to only one HTTP request, avoiding HTTP overhead and network congestion.

- As dependencies do not change, they can also be cached and we can skip pre-bundling.

 

2. Source code often contains non-plain JavaScript that needs transforming(e.g JSX, CSS) and will be edited very often. Vite는 네이티브 ESM을 통해 소스코드를 제공합니다. 

 

native ESM은 무엇이며 어떻게 개발 서버 시작시간을 개선할 수 있을까요?

ESM은 ECMAScript 모듈의 약자입니다. 최근 자바스크립트 언어 사양에 추가도니 것으로, 자바스크립트 애플리케이션에서 모듈을 로드하는 방법을 다룹니다. 

 

Benefits of building a dev server around native ESM

- There is no need for bundling. That's a big chunk of work that you don't have to do anymore.

- 네이티브 ESM은 본질적으로 온디맨드 방식입니다. 브라우저 요청에 따라 Vite는 필요에 따라 소스 코드를 변환하여 제공합니다. 특정 화면에 모듈이 필요하지 않은 경우 처리되지 않습니다. 이 다이어그램은 필요한 모듈만 로드된 상태로 네이티브 ESM 기반 개발 서버가 시작되는 과정을 보여줍니다. 

 

 

2. Less waiting time for reflecting file updates

코드 베이스의 크기가 커지면 CRA에서 파일 업데이트 속도가 느려집니다. Vite는 그렇지 않습니다. Vite가 파일 업데이트를 처리하는 방식을 알아봅시다.

 

- Vite에서 HMR은 네이티브 ESM을 통해 수행됩니다. 파일을 편집하면 Vite는 편집된 모듈과 가장 가까운 HML 경계 사이의 체인을 무효화합니다.(When a file is edited, Vite invalidates the chain between the edited module and its closest HTML boundary.) This makes HTML updates simple and fast regardless of the size of your application.

- 모듈은 HTTP 요청을 통해 가져옵니다. Vite는 캐싱을 위해 HTTP 헤더를 활용하여 전체 페이지 리로딩 속도를 높입니다. 소스코드 모듈 요청은 304 Not Modified를 통해 조건부로 이루어집니다. 그리고 dependency module 요청은 Cache-Control: max-age=31536000, 변경 불가능으로 캐시 제어를 통해 캐시됩니다. 

 

3. Improved build performance

Vite에는 다양한 성능 최적화를 즉시 적용하는 pre-configured build command가 포함되어 있습니다.

 

1. Async chunk loading optimization

 

code splitting에서 웹팩 및 롤업은 공통 청크(두 개 이상의 다른 청크 간에 공유하는 코드)를 생성합니다. 이를 dynamic import와 결합하면 많은 네트워크 왕복이 발생할 수 있습니다.

 

 

최적화되지 않은 시나리오의 이미지에서 볼 수 있듯이 비동기 청크 A를 가져올 때 브라우저는 먼저 A를 요청하고 parsing하지 않고는 공통 청크 C가 필요하다는 것을 알지 못합니다. 브라우저는 공통 청크 C가 필요하다는 것을 파악한 후 이를 가져와서 추가 네트워크 왕복이 발생합니다. 

 

Entry -> A -> C

 

Whereas, Vite rewrites code-split dynamic import calls with a preload step. When A is requested, C is fetched in parallel. This eliminates network round trips.

 

Entry -> (A + C)

 

2. CSS code splittingVite는 모듈에서 사용하는 CSS를 비동기 청크에서 자동으로 추출하여 별도의 파일로 생성합니다. 연결된 비동기 청크가 로드될 때 <link> 태그를 통해 CSS 파일이 자동으로 로드됩니다.

 

4. Rich features

Vite는 타입스크립트, JSX, CSS등을 지원합니다. 

 

- TypeScript: Vite supports importing '.ts' files out of the box. It uses esbuild to transpile TypeScript into JavaScript which is about 20 ~ 30x faster than vanilla tsc. The HMR updates can reflect in the browser in under 50ms.

- JSX: Vite supports '.jsx' and '.tsx' files out of the box. JSX transpilation is handled via esbuild.

- CSS: Importing '.css' files injects content to the page via a '<style>' tag with HMR support.

- JSON: JSON files can be directly imported into Vite. It also supports named imports.

- Dynamic Imports: Dynamic import with variables can be used with Vite.