Next/bundle-analyzer를 활용한 번들 사이즈 최적화

sangsang·2024년 4월 14일
3

번들링이란?

번들링은 개발 과정에서 작성된 다양한 코드 파일들을 하나 또는 여러 개의 파일로 묶는 과정을 의미한다. 이 과정은 애플리케이션의 로딩 시간을 단축시키고, 브라우저가 파일을 더욱 빠르게 해석할 수 있도록 도와준다.

번들링의 중요성

번들링을 통해 파일 크기를 감소시키는 것은 웹 애플리케이션의 성능을 향상시키는 핵심 요소이다. 다음과 같은 방법으로 이루어진다

번들 사이즈가 증가하면 페이지 로딩 및 실행 시간이 증가하게 되며, 사용자 경험을 저하시키는 주된 요인 중 하나다. 디자이너는 이미지 크기를 최적화하고, 개발자는 스크립트 파일의 크기를 줄이는 데 집중해야 한다.

번들 사이즈 최적화 방법

  1. 크기가 작은 라이브러리로 교체
    동일/ 유사한 기능의 라이브러리 중 크기가 작은 라이브러리로 교체

Bundlephobia
패키지의 번들 사이즈, 다운로드 시간, 그리고 다른 패키지와의 비교 사이트

  1. Tree Shaking을 통한 최적화

Tree Shaking
사용되지 않는 코드(Dead Code)를 제거하여 번들의 크기를 줄이는 과정.
이 기술은 모듈 번들러가 ES2015+의 모듈 시스템(즉, import와 export 구문)을 사용하는 코드에서 미사용 모듈을 식별하고 제거한다.

Tree Shaking을 통한 최적화 비교

번들 사이즈 분석/시각화 도구 'Bundle size analyzer'를 사용해 번들 사이즈를 분석하고, Tree Shaking 전/후를 시각적으로 비교해보았다.

Bundle size analyzer
번들 사이즈 분석 시각화 도구

  • Next.js 프로젝트용: @next/bundle-analyzer
$npm install -D @next/bundle-analyzer
  • next.config.js 파일 수정
    • withBundleAnalyzer 준비
    • env 변수 ANALYZE 값에 따라 실행 결정
const withBundleAnalyzer = require("@next/bundle-analyzer")
({ enabled: process.env.ANALYZE === "true" });
module.exports = withBundleAnalyzer(nextConfig);
  • 환경변수 설정을 위한 cross-env 설정
$ npm install -D cross-env
  • Package.json 내 analyzer 실행 커멘드 적용
  "scripts": {
	//...
    "analyze": "cross-env ANALYZE=true npm run build"
    //...
  },

Barrel import 했을 때

export {Eye, EyeSlash} from '@assets/icons';
  • 70개의 아이콘을 index.ts에서 barrel import 했을 때,
    Start size: 121.04KB
    Parsed size: 85.12 KB
    Gzipped size: 38.82 KB

  • 13개 이미지 파일을 index.ts에서 Barrel import 했을 때,
    Start size: 143.51KB
    Parsed size: 113.5 KB
    Gzipped size: 18.48 KB

Default import로 수정했을 때

  • 아이콘 파일

  • 이미지 파일
    이미지 파일은 측정이 안 될 정도로 사이즈가 작아졌다.

최적화 결과

First Load JS Shared by all : 188 KB 에서 80.5 KB로 감소

  • 최적화 전

  • 최적화 후

평가

바렐 파일을 사용하지 않고 각 컴포넌트를 독립적인 모듈로 분리하여 번들 사이즈를 크게 줄일 수 있었다. 추가로, 각 컴포넌트가 필요할 때만 로드하도록 next/dynamic을 사용한다면 초기 로드 시 번들 크기를 더욱 줄일 수 있을 것 같다. 추후에 next/dynamic도 적용해봐야겠다.

  • next/dynamic 예시 코드
import dynamic from 'next/dynamic';

const DynamicEye = dynamic(() => import('@assets/icons/Eye.svg'));
const DynamicEyeSlash = dynamic(() => import('@assets/icons/EyeSlash.svg'));

참고자료

profile
개발이 너무 좋다. 정말 잘 하고 싶다.

0개의 댓글

관련 채용 정보