OPEN HYPER STEP
← 목록으로 (stack-analysis)
STACK-ANALYSIS · 93 / 120
stack-analysis
CHAPTER 93 / 120
읽기 약 2
FUNCTION

번들 최적화: Tree Shaking + Code Splitting


핵심 개념

webpack/rollup·dynamic import·side effects·analyze — JS 80% 감소.

본문

Tree Shaking 작동 조건

📋 코드 (14줄)
1. ESM (import/export) — CommonJS 안 됨
2. side effects 표시 (package.json)
3. 사용 안 하는 코드는 export 안 됨


// package.json
{
  "sideEffects": false  // 모든 import 제거 가능
}

// 또는 일부만 부수효과
{
  "sideEffects": ["./src/polyfills.ts", "*.css"]
}

잘못된 import — Tree shaking 안 됨

TYPESCRIPT📋 코드 (18줄)
// ❌ 전체 lodash (70KB)
import _ from 'lodash';
_.debounce(fn, 300);


// ❌ named import도 lodash main entry는 CJS
import { debounce } from 'lodash';
// → 여전히 전체 import


// ✅ 개별 entry import
import debounce from 'lodash/debounce';
// → 1KB만


// ✅ lodash-es (ESM 버전)
import { debounce } from 'lodash-es';
// → tree-shake 가능

큰 라이브러리 대체

📋 코드 (9줄)
| 라이브러리 | 크기 | 대체 | 크기 |
|---|---|---|---|
| moment | 290KB | date-fns | 13KB (필요한 함수만) |
| moment | 290KB | dayjs | 7KB |
| lodash | 70KB | lodash-es + named | 5KB |
| jquery | 87KB | vanilla JS | 0KB |
| chart.js | 200KB | recharts | 90KB |
| chart.js | 200KB | uPlot | 40KB |
| axios | 35KB | fetch + ofetch | 5KB |

Code Splitting — Dynamic Import

TSX📋 코드 (25줄)
// 라우트별 자동 분할 (Next.js)
// app/heavy/page.tsx → 별도 chunk


// 컴포넌트 동적 로드
import dynamic from 'next/dynamic';

const HeavyChart = dynamic(() => import('@/components/HeavyChart'), {
  loading: () => <Skeleton />,
  ssr: false,
});


// 조건부 로드
async function showEditor() {
  const { Editor } = await import('@tiptap/react');
  return <Editor />;
}


// 라이브러리 — 사용 시점에만
const handleExport = async () => {
  const XLSX = await import('xlsx');
  XLSX.writeFile(...);
};

라우트별 prefetch

TSX📋 코드 (14줄)
import Link from 'next/link';

<Link href="/heavy" prefetch>  {/* 호버 시 prefetch */}
  무거운 페이지
</Link>


// 수동 prefetch
import { useRouter } from 'next/navigation';

const router = useRouter();
useEffect(() => {
  router.prefetch('/heavy');
}, []);

번들 분석 — @next/bundle-analyzer

BASH📋 코드 (1줄)
pnpm add -D @next/bundle-analyzer
JAVASCRIPT📋 코드 (6줄)
// next.config.js
const withBundleAnalyzer = require('@next/bundle-analyzer')({
  enabled: process.env.ANALYZE === 'true',
});

module.exports = withBundleAnalyzer({});
BASH📋 코드 (3줄)
ANALYZE=true pnpm build
# → /analyze/client.html, server.html 자동 열림
# → 큰 chunk 식별

일반적인 큰 chunk 원인

📋 코드 (19줄)
1. Polyfills
   - core-js, regenerator-runtime
   → modern browsers 대상이면 제거

2. 큰 라이브러리
   - moment, lodash, antd
   → 위 대체 표 참조

3. Locales
   - moment locale 모두 포함
   → 필요한 것만 import

4. Source Maps in production
   - 의도치 않게 포함
   → productionBrowserSourceMaps: false (Next.js)

5. Duplicate dependencies
   - 같은 라이브러리 다른 버전
   → pnpm dedupe / npm dedupe

ES2020+ 타깃

JAVASCRIPT📋 코드 (19줄)
// next.config.js — 모던 브라우저만
module.exports = {
  compiler: {
    // 구 브라우저 polyfill 제거
  },
};


// .browserslistrc
> 0.5%
last 2 versions
not dead
not ie 11
not op_mini all


// 결과
// - 폴리필 80% 감소
// - 코드 transpilation 최소

측정 — performance budget

JAVASCRIPT📋 코드 (28줄)
// next.config.js
module.exports = {
  experimental: {
    bundlePagesRouterDependencies: true,
  },
  // budget 검증 (CI)
  webpack: (config) => {
    config.performance = {
      maxAssetSize: 250000,        // 250KB
      maxEntrypointSize: 400000,   // 400KB
      hints: 'error',              // 초과 시 빌드 실패
    };
    return config;
  },
};


// Lighthouse CI에 budget.json
[
  {
    "path": "/*",
    "resourceSizes": [
      { "resourceType": "script", "budget": 300 },
      { "resourceType": "image", "budget": 500 },
      { "resourceType": "total", "budget": 1500 }
    ]
  }
]

다음 챕터

CH.94 "렌더링 전략: SSR vs SSG vs ISR vs CSR".


AI 프롬프트
🤖 AI에게 잘 물어보는 법 — 모델·전략별 프롬프트
Claude

무료: Sonnet 4.6 / Pro $20/mo: Opus 4.6

내 코드의 번들 최적화 부분을 분석해서
실전 분석 + 개선 우선순위를 알려줘.
ChatGPT

무료: GPT-5.5 / Plus $20/mo: GPT-5.5 Pro

번들 최적화 관련 베스트 프랙티스 5가지를
비교 분석해서 패턴 추출를 알려줘.
Gemini

무료: 2.5 Flash / Pro $19.99/mo: 3.1 Pro

내 프로젝트 전체에서 번들 최적화
최적화 가능 위치를 보고해줘.
Grok

무료: Grok 4.1 / SuperGrok $30/mo

2026년 한국 시장의 번들 최적화
트렌드를 솔직히 알려줘.

⭐ 이것만 기억하세요
번들 최적화: Tree Shaking + Code Splitting 이 3가지만 확실히 잡으세요
1.Tree shaking은 ESM + sideEffects:false — CommonJS는 안 됨
2.lodash-es / dayjs / native fetch로 대체 = 200KB 절감
3.dynamic import + bundle analyzer = 큰 chunk 식별 + 분할


공유하기
진행도 93 / 120