stack-analysis
CHAPTER 19 / 90
읽기 약 2분
FUNCTION
성능 최적화: 번들 분석 + 코드 스플리팅 + Suspense
핵심 개념
@next/bundle-analyzer·dynamic import·Suspense·Streaming SSR — Lighthouse 95+.
본문
번들 분석
pnpm add -D @next/bundle-analyzer// next.config.js
const withBundleAnalyzer = require('@next/bundle-analyzer')({
enabled: process.env.ANALYZE === 'true',
});
module.exports = withBundleAnalyzer({
// ... 기존 설정
});ANALYZE=true pnpm build
# → /analyze/client.html 자동 열림
# → 큰 chunk 식별 (lodash, moment, chart.js 등)동적 import — 코드 스플리팅
// 무거운 컴포넌트 — 필요할 때만 로드
import dynamic from 'next/dynamic';
const HeavyChart = dynamic(() => import('@/components/HeavyChart'), {
loading: () => <p>차트 로딩 중...</p>,
ssr: false, // 클라이언트만 (브라우저 API 의존)
});
const RichEditor = dynamic(
() => import('@tiptap/react').then(mod => mod.EditorContent),
{ ssr: false }
);
export default function Page() {
const [showChart, setShowChart] = useState(false);
return (
<>
<button onClick={() => setShowChart(true)}>차트 보기</button>
{showChart && <HeavyChart />}
</>
);
}Suspense + Streaming
// app/dashboard/page.tsx
import { Suspense } from 'react';
export default function Dashboard() {
return (
<div>
<h1>대시보드</h1>
{/* 빠른 데이터 — 즉시 렌더 */}
<UserProfile />
{/* 느린 데이터 — 스트리밍 */}
<Suspense fallback={<RevenueSkeleton />}>
<RevenueChart />
</Suspense>
<Suspense fallback={<ActivitySkeleton />}>
<RecentActivity />
</Suspense>
</div>
);
}
async function RevenueChart() {
const data = await fetchRevenue(); // 3초 걸림
return <Chart data={data} />;
}
async function RecentActivity() {
const items = await fetchActivity(); // 1초 걸림
return <Activity items={items} />;
}
// → 페이지가 즉시 응답 시작
// → 빠른 부분 먼저 렌더
// → 느린 부분은 준비되는 대로 스트리밍loading.tsx (자동 Suspense)
app/posts/
├── layout.tsx
├── loading.tsx # 자동 fallback
└── page.tsx// app/posts/loading.tsx
export default function Loading() {
return (
<div className="skeleton-grid">
{Array.from({ length: 6 }).map((_, i) => (
<div key={i} className="skeleton-card" />
))}
</div>
);
}큰 라이브러리 대체
// ❌ moment (290KB)
import moment from 'moment';
// ✅ date-fns (tree-shake, 수 KB)
import { format, parseISO } from 'date-fns';
// ❌ lodash 전체 (70KB)
import _ from 'lodash';
// ✅ named import (KB)
import debounce from 'lodash/debounce';
// ❌ chart.js (200KB+)
// ✅ recharts (60KB) 또는 자체 SVG핵심 지표 (Web Vitals)
LCP (Largest Contentful Paint): < 2.5s
→ 히어로 이미지 priority + 폰트 preload
FID/INP (Interaction to Next Paint): < 200ms
→ 무거운 JS 분할 + Web Worker
CLS (Cumulative Layout Shift): < 0.1
→ 이미지 width/height + 폰트 size-adjust다음 챕터
CH.20 "에러 바운더리 + 로딩 UI + 스트리밍 SSR" — 견고한 UX.
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년 한국 프론트엔드 시장의 성능 최적화 트렌드를 솔직히 알려줘.
⭐ 이것만 기억하세요
성능 최적화: 번들 분석 + 코드 스플리팅 + Suspense는 이 3가지만 확실히 잡으세요
1.번들 분석 → 큰 chunk 식별 → 동적 import 또는 대체 라이브러리
2.Suspense + Streaming = 페이지 즉시 응답 + 점진 렌더
3.loading.tsx 파일로 자동 Suspense — Next.js App Router 표준
공유하기
진행도 19 / 90