Published on

프론트 앱 빌드최적화 리서치

Authors
  • avatar
    Name
    sulmo
    Twitter

빌드 시간 단축 방법 리스트

  1. 순환 참조 확인 (store를 사용하는 케이스가 대부분. vuex 제거 하면 많이 사라질듯 함)
  2. 빌드 프로파일링으로 병목 파악
  3. 다중 스레드 및 병렬 처리 활용:
  • vite-plugin-parallel 같은 플러그인을 활용하여 병렬 빌드를 설정할 수 있습니다. 특히 CPU 코어가 많은 환경에서는 병렬 처리를 통해 빌드 시간을 줄일 수 있습니다.
  1. 의존성 최적화 및 캐싱
  • optimizeDeps 설정을 통해 상용 배포에서 필요한 핵심 의존성만 사전 번들링되도록 제한합니다. includeexclude를 통해 불필요한 모듈 번들링을 피할 수 있습니다.
  • Vite는 빌드 캐시를 활용합니다. .vite 캐시 디렉토리를 SSD에 두거나, 필요한 경우 클린 빌드를 진행하여 성능을 최적화합니다.
  1. Rollup 설정 커스터마이징
  • Vite는 Rollup을 통해 번들링을 처리하므로 build.rollupOptions.output.manualChunks 설정을 사용해 필요한 코드만 포함되도록 조정합니다.
  • 동적 import와 lazy-loading을 활용하여 코드 스플리팅을 세밀하게 설정하면 초기 빌드 크기와 시간 모두 줄일 수 있습니다.

    동적 import를 진행해도 빌드하는 파일의 양은 같은데 왜 빌드 시간이 줄어드나?

    • 빌드도구의 발전으로 분기시점이 명확한 파일을 병렬로 빌드하거나 재빌드하지 않음.
  1. CDN을 활용한 외부화
  • 상용 배포 시, 일반적인 라이브러리(예: Vue, lodash)를 CDN으로 불러올 수 있다면 rollupOptions.external을 통해 번들에서 제외하세요. CDN으로 불러오는 라이브러리는 빌드 과정에서 번들에 포함되지 않으므로 빌드 시간이 단축됩니다. (하지만 구축건 케이스가 있어 사용불가)
  1. CSS 최적화
  • TailwindCSS와 같은 스타일을 사용 중이라면 JIT 모드를 활성화해 불필요한 CSS를 줄입니다.
  • Vite에서 기본 CSS 코드 스플리팅이 설정되어 있어 사용하지 않는 CSS를 배포 시 포함하지 않도록 설정하세요.
  1. Minify 설정 조정
  • esbuild가 기본적으로 사용되고 있음. 다른 빌더 보다 기본적으로 20 ~ 40배 빠름. (이미 되어있음)

빌드 트래킹 방식

Node.js의 --inspect 옵션

메모리와 CPU사용량을 추적하는데 사용할 수 있다. 단, 실행중인 클라이언트를 위함이며, 기본적으로 127.0.0.1:9229 를 수신중이라고 한다.

그래서 실행중인 웹앱에서 특정 액션이나 작동중에 발생하는 메모리 누수나 cpu 작업을 추적할 때 사용한다.

보통 실시간으로 녹화모드로 진행하여 앱의 특정 구간에서 브라우저 렌더링 블락이나, 브라우저 힙메모리의 누수를 체크할 때 사용하는 용도가 더 적합하다. 메모리 누수 사용사례

앱 빌드 단계에서 메모리를 트래킹하는 건 --heap-porf 옵션을 알아보자.


Node.js 빌드 메모리 사용 트래킹

Vite는 Node.js 위에서 돌아간다. Node.js 프로세스의 메모리 사용량 객체에 접근하여 트래킹할 수 있다. 사용 방식은 vite의 Plugin api에서 제공하는 라이프 사이클 콜백 내부에서 사용하면 된다.

  • Node.js process.memoryUsage() 사용vite.config.ts나 빌드 스크립트에 process.memoryUsage()를 추가하여 빌드 단계별 메모리를 확인할 수 있다.
import { defineConfig } from 'vite';
export default defineConfig({
	build: {
		outDir: 'dist',
		rollupOptions: {
			plugins: [ {
				name: 'memory-logger',
				generateBundle() { const used = process.memoryUsage();
				console.log('Memory Usage:', {
					rss: `${(used.rss / 1024 / 1024).toFixed(2)} MB`,
					heapTotal: `${(used.heapTotal / 1024 / 1024).toFixed(2)} MB`,
					heapUsed: `${(used.heapUsed / 1024 / 1024).toFixed(2)} MB`,
					external: `${(used.external / 1024 / 1024).toFixed(2)} MB`,
				});
			},],
		},
	},
});
  • 결과를 CSV로 출력하거나 파일로 저장하여 비교하면 빌드 전후의 메모리 사용량을 분석할 수 있다.

Vite의 --profile 플래그 사용

Vite의 --profile 플래그를 사용하면 Rollup 빌드 단계에서 각 단계에 소비된 리소스 정보를 JSON 형식으로 저장한다.

vite build --profile

빌드가 완료되면 vite-profile.json 파일이 생성되며, 이를 통해 각 플러그인이나 빌드 단계가 소비한 리소스를 분석할 수 있다.

이 파일을 Chrome 개발자 도구의 Performance 탭에 업로드해 스레드에서 작업이 어떤 순서로 얼마만큼의 시간이 걸리는지 확인할 수 있다. (또는 여기 업로드하여 확인가능)

다만, 메모리 사용량은 포함되지 않으므로 다른 도구와 병행해야 한다.

추가적인 상세 개선방식들은 공식문서에서

vite-plugin-inspect

vite plugin 사용에대한 검사기

실제로 메모리에대한 데이터가 기록되지 않아 plugin을 사용해 보았다. https://github.com/antfu-collective/vite-plugin-inspect

각 파일 별 vite에서 사용하나 플러그인 작업 시간이나 상태값들 변경사항들을 볼 수 있지만, 메모리 사용량에대한 정보는 없다.


Node.js 힙 프로파일링 사용

Node.js의 --heap-prof 플래그를 사용하여 힙 프로파일을 생성할 수 있다.

node --heap-prof vite build

이 명령어를 실행하면 빌드 과정이 끝난 후 .heapprofile 파일이 생성된다. 이 파일을 Chrome DevTools의 Memory 탭에서 로드하여 메모리 사용량을 분석할 수 있다.


OS 레벨 메모리 트래킹 (e.g., time 명령어)

운영 체제의 메모리 사용량 추적 도구를 활용하면 Vite 프로세스의 전체 메모리 사용량을 확인할 수 있다.

  • Linux/macOS: time 명령어

/usr/bin/time -v vite build

빌드가 완료되면 "Maximum resident set size"와 같은 메모리 사용량 정보를 출력한다.