---
id: wiki-2026-0508-code-splitting
title: Code Splitting
category: 10_Wiki/Topics
status: verified
canonical_id: self
aliases: [Bundle Splitting, Dynamic Import]
duplicate_of: none
source_trust_level: A
confidence_score: 0.9
verification_status: applied
tags: [bundling, performance, webpack, vite, frontend]
raw_sources: []
last_reinforced: 2026-05-10
github_commit: pending
tech_stack:
language: TypeScript
framework: Vite / Webpack / Next.js
---
# Code Splitting
## 매 한 줄
> **"매 bundle 의 chunk 의 분리, on-demand load 의 first-paint 단축"**. Code Splitting 은 dynamic `import()` + bundler chunking 의 결합 의 매 monolithic JS bundle 의 분해. 2026 Vite/Rspack/Turbopack 시대 에 route-level + component-level + vendor split 의 매 표준.
## 매 핵심
### 매 splitting 의 axis
- **Route-based**: 각 page 의 separate chunk — 매 SPA / Next.js 의 default
- **Component-based**: heavy component 의 lazy (Modal, Chart, Editor)
- **Vendor**: `node_modules` 의 separate chunk — long-term cache
- **Dynamic feature**: locale, A/B variant 의 conditional load
### 매 mechanism
- **Dynamic `import()`**: ECMAScript spec — Promise 의 return
- **Bundler 의 split point detection**: `import()` 호출 의 chunk boundary
- **Manifest**: hashed filename 의 mapping
- **Preload / prefetch**: `` hint
### 매 cost trade-off
- **Pro**: initial bundle 의 작아짐 → faster TTI
- **Con**: extra HTTP request, waterfall 위험 — preload 의 mitigate
### 매 응용
1. Route-level lazy (React Router, Next.js).
2. Modal / dialog (open 시 load).
3. Heavy editor (Monaco, CodeMirror).
4. Chart library (Recharts, ECharts).
5. i18n locale chunk.
## 💻 패턴
### React.lazy + Suspense
```tsx
import { lazy, Suspense } from 'react';
const Settings = lazy(() => import('./Settings'));
export default function App() {
return (
}>
);
}
```
### Next.js dynamic
```tsx
import dynamic from 'next/dynamic';
const Chart = dynamic(() => import('@/components/Chart'), {
loading: () =>
Loading chart...
,
ssr: false, // browser-only
});
export default function Dashboard() {
return ;
}
```
### Route-level (React Router v6)
```tsx
import { lazy } from 'react';
import { createBrowserRouter, RouterProvider } from 'react-router-dom';
const router = createBrowserRouter([
{ path: '/', lazy: () => import('./routes/Home') },
{ path: '/about', lazy: () => import('./routes/About') },
{ path: '/admin/*', lazy: () => import('./routes/Admin') },
]);
export default function App() {
return ;
}
```
### Vite의 manualChunks
```ts
// vite.config.ts
import { defineConfig } from 'vite';
export default defineConfig({
build: {
rollupOptions: {
output: {
manualChunks: {
react: ['react', 'react-dom'],
ui: ['@radix-ui/react-dialog', '@radix-ui/react-tabs'],
charts: ['recharts', 'd3'],
},
},
},
},
});
```
### Webpack magic comment
```ts
const Editor = () => import(
/* webpackChunkName: "editor" */
/* webpackPrefetch: true */
'./Editor'
);
```
### Conditional import (locale)
```ts
async function loadLocale(lang: string) {
const messages = await import(`./locales/${lang}.json`);
return messages.default;
}
```
### Preload critical chunk
```html
```
```tsx
// React: preload on hover
import('./Settings')}
>
Settings
```
### Module Federation (micro-frontend)
```ts
// host webpack.config.js
new ModuleFederationPlugin({
remotes: {
checkout: 'checkout@https://cdn/checkout/remoteEntry.js',
},
});
// usage
const Checkout = lazy(() => import('checkout/Cart'));
```
## 매 결정 기준
| 상황 | Approach |
|---|---|
| SPA, multi-page | Route-based split |
| Heavy modal / editor | `lazy()` + Suspense |
| Vendor lib stable | manualChunks vendor split |
| SSR + browser-only | `dynamic({ ssr: false })` |
| Independent deploy | Module Federation |
| Hover-triggered | preload on intent |
**기본값**: route-based + heavy-component lazy + vendor chunk.
## 🔗 Graph
- 부모: [[Web Performance]]
- 변형: [[Module Federation]]
- 응용: [[Lazy-Loading-Strategies|Lazy Loading]]
- Adjacent: [[Vite]] · [[Next.js]] · [[Suspense]]
## 🤖 LLM 활용
**언제**: route lazy, heavy component 의 split, vendor chunking 코드 generation.
**언제 X**: 매 small app (10kb 의 split 의 overhead 가 더 큼).
## ❌ 안티패턴
- **너무 fine-grained split**: 100개 chunk → request flood — 매 ~10-30 chunk 의 sweet spot.
- **Waterfall**: A → B → C 의 sequential — 매 parallel preload.
- **Vendor chunk 의 무한 growth**: dependency 추가 시 cache invalidation — 매 stable lib 만 vendor.
- **Suspense 의 boundary 누락**: error / blank screen.
- **`ssr: false` 의 abuse**: SEO 손실.
## 🧪 검증 / 중복
- Verified (Vite docs, Webpack docs, Next.js docs, React 19).
- 신뢰도 A.
## 🕓 Changelog
| 날짜 | 변경 |
|---|---|
| 2026-05-08 | Phase 1 |
| 2026-05-10 | Manual cleanup — splitting strategies + bundler config + MF |