Files
2nd/10_Wiki/Topics/Domain_Programming/Frontend/Code Splitting.md
T
Antigravity Agent c24165b8bc refactor(topics): 멀티 에이전트용 지식 재편 — _Common(공통 기본기) + Domain_* 구조
에이전트 8종(대화형/프로그래머 C·S/디자이너/설계자/기획자/QA/PD/PM)에게
[공통 기본 능력 + 롤별 Specialty] 2층으로 지식을 주입하기 위한 재분류.
문서 내용·포맷은 무수정, 폴더 이동만 (6,372개 문서 수 보존 확인).

- Topic_Programming → Domain_Programming (내부 구조 보존)
- Topic_Graphic → Domain_Design
- Topic_Business → Domain_Product
- Topic_General → Domain_General
- _Common 신설: Math(구 Topic_Math_Specialty), Reasoning(구 General/From_Thinking & Reasoning),
  Reasoning_Creativity(구 General/From_창의성), Communication(Poetic_Blog_Writing + From_writing)
- 타 도메인의 From_* 폴더는 유지 (출처 표기일 뿐, 이미 도메인에 맞게 분류된 문서)
- 빈 폴더 정리 (memory/procedures)
- 에이전트→폴더 매핑은 workspace의 .astra/agent-knowledge-map.json (9개 에이전트)

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-11 11:05:56 +09:00

5.2 KiB

id, title, category, status, canonical_id, aliases, duplicate_of, source_trust_level, confidence_score, verification_status, tags, raw_sources, last_reinforced, github_commit, tech_stack
id title category status canonical_id aliases duplicate_of source_trust_level confidence_score verification_status tags raw_sources last_reinforced github_commit tech_stack
wiki-2026-0508-code-splitting Code Splitting 10_Wiki/Topics verified self
Bundle Splitting
Dynamic Import
none A 0.9 applied
bundling
performance
webpack
vite
frontend
2026-05-10 pending
language framework
TypeScript 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: <link rel="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

import { lazy, Suspense } from 'react';

const Settings = lazy(() => import('./Settings'));

export default function App() {
  return (
    <Suspense fallback={<Spinner />}>
      <Settings />
    </Suspense>
  );
}

Next.js dynamic

import dynamic from 'next/dynamic';

const Chart = dynamic(() => import('@/components/Chart'), {
  loading: () => <p>Loading chart...</p>,
  ssr: false, // browser-only
});

export default function Dashboard() {
  return <Chart data={data} />;
}

Route-level (React Router v6)

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 <RouterProvider router={router} />;
}

Vite의 manualChunks

// 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

const Editor = () => import(
  /* webpackChunkName: "editor" */
  /* webpackPrefetch: true */
  './Editor'
);

Conditional import (locale)

async function loadLocale(lang: string) {
  const messages = await import(`./locales/${lang}.json`);
  return messages.default;
}

Preload critical chunk

<link rel="modulepreload" href="/assets/Settings-abc123.js">
// React: preload on hover
<Link
  to="/settings"
  onMouseEnter={() => import('./Settings')}
>
  Settings
</Link>

Module Federation (micro-frontend)

// 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

🤖 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