노트

번들 크기 줄이기

Bundle Size Reduction

프론트엔드#performance#tooling · 연결된 개념 14개

쉽게 말하면

번들 다이어트는 여행 가방이 무거울 때 먼저 저울에 달아 보고, 겹치는 짐과 안 쓸 짐을 빼는 일이에요. 사용자는 가방을 받기만 하는 게 아니라 풀어서 써야 하니 가벼울수록 빨리 움직여요.

비유의 한계 JS는 같은 무게라도 이미지보다 비싸요. 이미지는 받아서 디코딩만 하면 되지만 JS는 파싱·컴파일·실행까지 해야 해서, 줄이기 전에 bundle analyzer로 먼저 재는 게 순서예요.

번들 다이어트는 사용자가 내려받는 JavaScript 양을 측정하고 줄이는 작업이다. 같은 용량이라도 JS는 이미지보다 비싸다. 이미지는 다운로드와 디코딩만 하면 되지만, JS는 다운로드·파싱·컴파일·실행을 모두 거친다.

순서

  1. 먼저 잰다. Webpack Bundle Analyzer나 Next.js bundle analyzer로 어떤 라이브러리가 큰지 본다. 추측으로 시작하지 않는다(섣부른 최적화)
  2. 같은 라이브러리의 다른 버전이 중복 설치됐는지 본다. npm은 semver(Semantic Versioning)를 지킨다고 가정하고 호환되는 높은 버전 하나로 합칠 수 있는데, 그게 npm dedupe다. 패키지 매니저의 저장 방식은 npm과 pnpm 참고
  3. 무거운 라이브러리를 바꾼다. 용도가 겹치면 하나로 합치고, 작은 대안이나 네이티브 API(Application Programming Interface)로 대체한다. Bundlephobia에서 크기를 미리 확인할 수 있다
  4. 불필요한 폴리필(Polyfill)을 뺀다. 지원 브라우저를 기준으로 판단한다
  5. 라이브러리 영향을 페이지에 가둔다. 모든 페이지가 공유하는 공통 청크 하나에 넣으면 라이브러리를 하나 추가할 때마다 전 페이지가 무거워진다. 여러 청크로 나누고, 필요할 때만 받는 동적 임포트를 쓴다

배럴 파일을 거치지 않기

배럴 파일에서 하나만 import해도 배럴이 다시 내보내는 다른 모듈까지 불러오는 비용이 든다. 직접 경로로 import하거나, Next.js라면 experimental.optimizePackageImports에 패키지를 넣어 실제로 쓰는 모듈만 불러오게 한다(2026 기준 실험 옵션)

나중에 받을 청크를 미리 받기

webpack에서는 동적 임포트에 매직 코멘트(Magic Comments)를 달아 리소스 힌트를 낼 수 있다.

import(/* webpackPrefetch: true */ './LoginModal')  // 다음 이동에서 쓸 듯한 청크
import(/* webpackPreload: true */ 'ChartingLibrary') // 지금 화면에서 곧 쓸 청크
  • webpackPrefetch: 부모 청크를 다 받은 뒤 <link rel="prefetch">를 붙인다. 브라우저는 한가할 때 받아 둔다
  • webpackPreload: <link rel="preload">로 부모 청크와 병렬로 바로 받는다. 부모 청크가 곧바로 요청할 청크에 쓴다. 잘못 쓰면 오히려 성능을 해친다

라이브러리를 만드는 쪽이라면

  • 트리 셰이킹이 되도록 ESM(ECMAScript Modules)으로 배포하고 sideEffects를 명시한다
  • 번들러가 순수 함수 호출을 지울 수 있게 /*#__PURE__*/ 주석을 단다(Terser 등이 이용)

출처: 토스 SLASH 21 - JavaScript Bundle Diet · Next.js - optimizePackageImports · Vercel - How we optimized package imports in Next.js · webpack - Code Splitting: Prefetching/Preloading modules · webpack - Module Methods: Magic Comments

연결된 개념

이 노트를 가리키는 문서

뜻이 가까운 노트

  • 번들러

    번들러(Bundler)는 모듈로 나뉜 소스 코드를 의존 관계(Dependency Graph)를 따라 묶고 변환해, 브라우저가 적은 요청으로 받을 수 있는 결과물로 만드는 빌드 도구다.

  • 버전 스큐와 정적 자산 오프로드

    버전 스큐(Version Skew)는 새 버전을 배포한 뒤에도 브라우저에 떠 있는 이전 빌드의 클라이언트가 새 서버와 통신하면서 생기는 불일치다. 대표 증상은 이전 HTML이 참조하던 JS 청크를 늦게 불러오려다 404가 나는 ChunkLoadError다.

  • 구성요소 줄이기

    셀 수 있는 모든 구성요소(파일, 폴더 깊이, 클래스, 함수, 분기, 변수, 테이블, 필드, 테스트 케이스…)는 비용이라는 관점. 심플 디자인의 네 번째 규칙을 실무 기준으로 풀어낸 것이다.

  • 반응형 웹 디자인

    하나의 페이지가 화면 크기와 기기에 맞춰 레이아웃·이미지·글자 크기를 바꾸도록 만드는 접근. 미디어 쿼리(Media Query), 유연한 레이아웃(Flexible Layout), 반응형 미디어(Responsive Media)가 세 축이다.

  • loading 경계와 레이아웃 끌어올리기

    Next.js App Router에서 loading.tsx는 같은 세그먼트의 page와 그 아래(하위 layout 포함)를 suspense로 감싸지만, **같은 세그먼트의 layout은 감싸지 않는다**. 그래서 데이터를 기다릴 필요가 없는 공통 UI(탭바, 필터 헤더)를 page에서 layout으로 끌어올리면 스켈레톤에 덮이지 않고 처음부터 실제 모습으로 보인다.

보기 옵션