← スキル一覧に戻る

performance-optimization
by supercent-io
⭐ 9🍴 2📅 2026年1月24日
SKILL.md
name: performance-optimization description: Optimize application performance for speed, efficiency, and scalability. Use when improving page load times, reducing bundle size, optimizing database queries, or fixing performance bottlenecks. Handles React optimization, lazy loading, caching, code splitting, and profiling. tags: [performance, optimization, React, lazy-loading, caching, profiling, web-vitals] platforms: [Claude, ChatGPT, Gemini]
Performance Optimization
When to use this skill
- 느린 페이지 로드: Lighthouse 점수 낮음
- 느린 렌더링: 사용자 인터랙션 지연
- 큰 번들 크기: 다운로드 시간 증가
- 느린 쿼리: 데이터베이스 병목
Instructions
Step 1: 성능 측정
Lighthouse (Chrome DevTools):
# CLI
npm install -g lighthouse
lighthouse https://example.com --view
# CI에서 자동화
lighthouse https://example.com --output=json --output-path=./report.json
Web Vitals 측정 (React):
import { getCLS, getFID, getFCP, getLCP, getTTFB } from 'web-vitals';
function sendToAnalytics(metric: any) {
// Google Analytics, Datadog 등으로 전송
console.log(metric);
}
getCLS(sendToAnalytics);
getFID(sendToAnalytics);
getFCP(sendToAnalytics);
getLCP(sendToAnalytics);
getTTFB(sendToAnalytics);
Step 2: React 최적화
React.memo (불필요한 리렌더링 방지):
// ❌ 나쁜 예: 부모가 리렌더링될 때마다 자식도 리렌더링
function ExpensiveComponent({ data }: { data: Data }) {
return <div>{/* 복잡한 렌더링 */}</div>;
}
// ✅ 좋은 예: props 변경 시에만 리렌더링
const ExpensiveComponent = React.memo(({ data }: { data: Data }) => {
return <div>{/* 복잡한 렌더링 */}</div>;
});
useMemo & useCallback:
function ProductList({ products, category }: Props) {
// ✅ 필터링 결과 메모이제이션
const filteredProducts = useMemo(() => {
return products.filter(p => p.category === category);
}, [products, category]);
// ✅ 콜백 메모이제이션
const handleAddToCart = useCallback((id: string) => {
addToCart(id);
}, []);
return (
<div>
{filteredProducts.map(product => (
<ProductCard key={product.id} product={product} onAdd={handleAddToCart} />
))}
</div>
);
}
Lazy Loading & Code Splitting:
import { lazy, Suspense } from 'react';
// ✅ Route-based code splitting
const Dashboard = lazy(() => import('./pages/Dashboard'));
const Profile = lazy(() => import('./pages/Profile'));
const Settings = lazy(() => import('./pages/Settings'));
function App() {
return (
<Suspense fallback={<div>Loading...</div>}>
<Routes>
<Route path="/dashboard" element={<Dashboard />} />
<Route path="/profile" element={<Profile />} />
<Route path="/settings" element={<Settings />} />
</Routes>
</Suspense>
);
}
// ✅ Component-based lazy loading
const HeavyChart = lazy(() => import('./components/HeavyChart'));
function Dashboard() {
return (
<div>
<h1>Dashboard</h1>
<Suspense fallback={<Skeleton />}>
<HeavyChart data={data} />
</Suspense>
</div>
);
}
Step 3: 번들 크기 최적화
Webpack Bundle Analyzer:
npm install --save-dev webpack-bundle-analyzer
# package.json
{
"scripts": {
"analyze": "webpack-bundle-analyzer build/stats.json"
}
}
Tree Shaking (사용하지 않는 코드 제거):
// ❌ 나쁜 예: 전체 라이브러리 임포트
import _ from 'lodash';
// ✅ 좋은 예: 필요한 것만 임포트
import debounce from 'lodash/debounce';
Dynamic Imports:
// ✅ 필요할 때만 로드
button.addEventListener('click', async () => {
const { default: Chart } = await import('chart.js');
new Chart(ctx, config);
});
Step 4: 이미지 최적화
Next.js Image 컴포넌트:
import Image from 'next/image';
function ProductImage() {
return (
<Image
src="/product.jpg"
alt="Product"
width={500}
height={500}
priority // LCP 이미지인 경우
placeholder="blur" // 블러 플레이스홀더
sizes="(max-width: 768px) 100vw, 50vw"
/>
);
}
WebP 포맷 사용:
<picture>
<source srcset="image.webp" type="image/webp">
<source srcset="image.jpg" type="image/jpeg">
<img src="image.jpg" alt="Fallback">
</picture>
Step 5: 데이터베이스 쿼리 최적화
N+1 쿼리 문제 해결:
// ❌ 나쁜 예: N+1 queries
const posts = await db.post.findMany();
for (const post of posts) {
const author = await db.user.findUnique({ where: { id: post.authorId } });
// 101번 쿼리 (1 + 100)
}
// ✅ 좋은 예: JOIN 또는 include
const posts = await db.post.findMany({
include: {
author: true
}
});
// 1번 쿼리
인덱스 추가:
-- 느린 쿼리 식별
EXPLAIN ANALYZE SELECT * FROM users WHERE email = 'test@example.com';
-- 인덱스 추가
CREATE INDEX idx_users_email ON users(email);
-- 복합 인덱스
CREATE INDEX idx_orders_user_date ON orders(user_id, created_at);
캐싱 (Redis):
async function getUserProfile(userId: string) {
// 1. 캐시 확인
const cached = await redis.get(`user:${userId}`);
if (cached) {
return JSON.parse(cached);
}
// 2. DB 조회
const user = await db.user.findUnique({ where: { id: userId } });
// 3. 캐시 저장 (1시간)
await redis.setex(`user:${userId}`, 3600, JSON.stringify(user));
return user;
}
Output format
성능 최적화 체크리스트
## Frontend
- [ ] React.memo로 불필요한 리렌더링 방지
- [ ] useMemo/useCallback 적절히 사용
- [ ] Lazy loading & Code splitting
- [ ] 이미지 최적화 (WebP, lazy loading)
- [ ] 번들 크기 분석 및 감소
## Backend
- [ ] N+1 쿼리 제거
- [ ] 데이터베이스 인덱스 추가
- [ ] Redis 캐싱
- [ ] API Response 압축 (gzip)
- [ ] CDN 사용
## 측정
- [ ] Lighthouse 점수 90+
- [ ] LCP < 2.5s
- [ ] FID < 100ms
- [ ] CLS < 0.1
Constraints
필수 규칙 (MUST)
- 측정 먼저: 추측하지 말고 프로파일링
- 점진적 개선: 한 번에 하나씩 최적화
- 성능 모니터링: 지속적으로 추적
금지 사항 (MUST NOT)
- 조기 최적화: 병목이 없는데 최적화하지 않음
- 가독성 희생: 성능을 위해 코드를 복잡하게 만들지 않음
Best practices
- 80/20 법칙: 20% 노력으로 80% 개선
- 사용자 중심: 실제 사용자 경험 개선에 집중
- 자동화: CI에서 성능 회귀 테스트
References
Metadata
버전
- 현재 버전: 1.0.0
- 최종 업데이트: 2025-01-01
- 호환 플랫폼: Claude, ChatGPT, Gemini
관련 스킬
태그
#performance #optimization #React #caching #lazy-loading #web-vitals #code-quality
Examples
Example 1: Basic usage
Example 2: Advanced usage
スコア
総合スコア
50/100
リポジトリの品質指標に基づく評価
✓SKILL.md
SKILL.mdファイルが含まれている
+20
○LICENSE
ライセンスが設定されている
0/10
○説明文
100文字以上の説明がある
0/10
○人気
GitHub Stars 100以上
0/15
○最近の活動
3ヶ月以内に更新がある
0/10
○フォーク
10回以上フォークされている
0/5
✓Issue管理
オープンIssueが50未満
+5
✓言語
プログラミング言語が設定されている
+5
○タグ
1つ以上のタグが設定されている
0/5
レビュー
💬
レビュー機能は近日公開予定です