performance-improve-process
SKILL.md
Performance Improvement Process
성능 개선의 전체 라이프사이클을 관리하는 프로세스 스킬입니다.
병목 탐색/측정은 perf-bottleneck-finder 스킬에 위임하고,
이 스킬은 프로세스 오케스트레이션에 집중합니다.
핵심 원칙 (Code Complete 2):
- 측정 없이 최적화하지 않는다
- 한 번에 하나만 변경한다
- 모든 변경은 되돌릴 수 있어야 한다
전체 프로세스
"느리다" 제보
│
▼
[Phase 1] 문제 정의 + Baseline 확보
│ └→ perf-bottleneck-finder 스킬에 위임
│ 결과: 병목 보고서 (구간별 시간 + 비율 + 우선순위)
▼
[Phase 2] 목표 설정
│ "4.3초 → 2초 이내"
▼
[Phase 3] 개선 사이클 (1순위 병목부터)
│ ┌──────────────────────────────┐
│ │ 변경 1개 적용 │
│ │ ↓ │
│ │ 재측정 (perf-bottleneck- │
│ │ finder 위임) │
│ │ ↓ │
│ │ 효과 판단 │
│ │ ├ 개선 → 유지, 기록 │
│ │ └ 악화/무효 → 롤백 │
│ │ ↓ │
│ │ 다음 병목으로 이동 │
│ └──────────────────────────────┘
▼
[Phase 4] 최종 보고
Before/After 비교 + 변경 이력
Phase 1: 문제 정의 + Baseline 확보
사용자에게 확인
성능 문제를 접수하면 아래 항목을 사용자에게 질문한다:
- 어디서 느린가? — 페이지, 화면, 기능
- 어떤 동작이 느린가? — 초기 로딩, 클릭 반응, 스크롤, 검색 등
- 얼마나 느린가? — 체감 시간
- 항상 느린가? — 재현 조건 (데이터 양, 특정 사용자 등)
- 목표 시간은? — 수용 가능한 응답 시간
perf-bottleneck-finder에 위임
문제가 정의되면 perf-bottleneck-finder 스킬을 호출하여 baseline을 확보한다.
위임 요청 형식:
perf-bottleneck-finder 스킬을 사용하여 다음을 측정해주세요:
- 대상: [URL 또는 페이지]
- 시나리오: [구체적 사용자 액션]
- 환경: [개발서버 포트, 데이터 상태 등]
위임 결과로 받는 것:
- 구간별 소요 시간 (ms)
- 전체 대비 비율 (%)
- 병목 우선순위 (1순위, 2순위, ...)
- 개선 방향 제안
Phase 2: 목표 설정
목표 설정 기준
| 유형 | 권장 목표 | 근거 |
|---|---|---|
| 페이지 초기 로딩 | < 2초 | Google UX 연구: 2초 이상에서 이탈률 급증 |
| 인터랙션 반응 | < 100ms | 사용자가 "즉각적"으로 느끼는 한계 |
| 애니메이션/스크롤 | < 16ms/frame | 60fps 유지 기준 |
| API 응답 (목록) | < 500ms | 체감 "빠르다" 기준 |
| API 응답 (단건) | < 200ms | 체감 "즉시" 기준 |
목표 기록
현재 상태: [측정값]
목표: [목표값]
개선 필요량: [차이]
예시:
현재 상태: 대시보드 로딩 4,332ms
목표: 2,000ms 이내
개선 필요량: -2,332ms 이상
Phase 3: 개선 사이클
핵심 원칙: 한 번에 하나만 변경한다
왜 한 번에 하나만?
여러 변경을 동시에 적용하면:
- 어떤 변경이 얼마나 기여했는지 알 수 없다
- 서로 상쇄하는 변경을 발견할 수 없다 (A는 +500ms, B는 -100ms)
- 악화된 변경을 개선된 변경이 가려버린다
- 롤백 시 어디까지 되돌려야 하는지 판단할 수 없다
사이클 실행
[Step 1] 1순위 병목에 대한 개선안 수립
│
│ 개선안은 구체적이어야 한다:
│ ❌ "쿼리를 최적화한다"
│ ✅ "orders 테이블의 date 컬럼에 B-tree 인덱스를 추가한다"
│
▼
[Step 2] 변경 적용 (git commit으로 기록)
git checkout -b perf/[개선대상]-[방법]
# 예: perf/orders-query-add-date-index
# 변경 적용
# ...
git commit -m "perf: [구체적 변경 내용]"
│
▼
[Step 3] 동일 조건에서 재측정
perf-bottleneck-finder 스킬에 재측정을 위임한다.
반드시 baseline과 동일한 조건(URL, 데이터, 환경)으로 측정한다.
│
▼
[Step 4] 효과 판단
┌───────────────────────────────────────────────┐
│ 변경: [변경 내용] │
│ 대상 구간: [구간명] │
│ Before: [이전 측정값] │
│ After: [새 측정값] │
│ 변화: [차이] ([비율]%) │
│ 판정: [유지 / 롤백 / 보류] │
└───────────────────────────────────────────────┘
│
▼
[Step 5] 유지 or 롤백 결정
효과 판단 기준
[유지] 조건 (모두 충족):
✅ 목표 방향으로 의미 있는 개선 (절대값 > 50ms AND 비율 > 5%)
✅ 다른 구간에 악영향 없음
✅ 코드 복잡성 증가가 수용 가능
[롤백] 조건 (하나라도 해당):
❌ 성능 악화 (어떤 크기든)
❌ 개선이 측정 오차 범위 이내 (< 2%)이면서 복잡성 증가
❌ 다른 구간에 의도치 않은 악영향
[보류] 조건:
⏸ 개선되었지만 부작용 의심 → 추가 테스트 필요
⏸ 효과가 경미하나 코드 품질 향상 → 사용자와 논의
사이클 반복
1순위 병목 개선 → 재측정 → 유지
│
▼ 목표 미달성 시
2순위 병목 개선 → 재측정 → 유지
│
▼ 목표 미달성 시
3순위 병목 개선 → ...
│
▼ 목표 달성 시
최종 보고
Phase 4: 롤백 전략
Git 기반 롤백 (기본)
# 마지막 변경만 롤백
git revert HEAD
# 특정 커밋 롤백
git revert <commit-hash>
# 브랜치 전략 활용 시
git checkout main
git branch -D perf/failed-optimization
변경 유형별 롤백 방법
| 변경 유형 | 적용 방법 | 롤백 방법 |
|---|---|---|
| 코드 변경 | git commit | git revert |
| DB 인덱스 | CREATE INDEX | DROP INDEX |
| DB 마이그레이션 | migration up | migration down |
| 설정 변경 | config 파일 수정 | git revert |
| 패키지 추가 | npm install | npm uninstall + lockfile restore |
| Feature Flag | 플래그 ON | 플래그 OFF (배포 불필요) |
롤백 원칙
- 변경 전에 롤백 방법을 먼저 확인한다 — 롤백할 수 없는 변경은 적용하지 않는다
- 변경과 롤백을 쌍으로 기록한다 — 변경 로그에 롤백 명령도 함께 작성
- 프로덕션은 Feature Flag로 — 코드 배포 없이 롤백 가능하도록
Phase 5: 최종 보고
모든 개선 사이클이 완료되면 최종 보고서를 작성한다.
┌──────────────────────────────────────────────────────┐
│ 성능 개선 최종 보고서 │
├──────────────────────────────────────────────────────┤
│ 시나리오: [대상] │
│ 기간: [시작일] ~ [완료일] │
│ 목표: [목표값] │
├──────────────────────────────────────────────────────┤
│ │
│ [ Before / After ] │
│ ────────────────────────────────────────── │
│ 전체 로딩 시간: 4,332ms → 1,820ms (-58%) │
│ API 응답 시간: 2,840ms → 450ms (-84%) │
│ 렌더링 시간: 1,390ms → 180ms (-87%) │
│ │
│ [ 적용된 변경 ] │
│ ────────────────────────────────────────── │
│ # 변경 내용 효과 │
│ 1. orders 테이블 인덱스 추가 -2,390ms │
│ 2. 대시보드 테이블 가상 스크롤 -1,210ms │
│ │
│ [ 롤백된 변경 ] │
│ ────────────────────────────────────────── │
│ # 변경 내용 사유 │
│ 3. API 응답 gzip 압축 효과 미미 (+2ms) │
│ │
│ [ 결론 ] │
│ 목표 2,000ms 이내 → 달성 (1,820ms) │
│ 주요 원인: DB 쿼리 미인덱싱 (62%), 대량 DOM 렌더 (32%) │
└──────────────────────────────────────────────────────┘
변경 로그 양식
개선 사이클마다 아래 형식으로 기록을 유지한다.
## 변경 #[N]
- 일시: [날짜]
- 대상 병목: [구간명] ([비율]%)
- 변경 내용: [구체적 변경]
- git commit: [커밋 해시]
- 측정 결과:
- Before: [값]ms
- After: [값]ms
- 변화: [차이]ms ([비율]%)
- 판정: [유지 / 롤백]
- 롤백 방법: [롤백 명령어]
자주 하는 실수
❌ 측정 없이 최적화
"useMemo를 추가하면 빨라질 것이다" → 추측
"React.memo로 감싸면 리렌더가 줄 것이다" → 추측
실제로 측정해보면:
- useMemo의 연산 자체가 0.1ms → 최적화 효과 무의미
- React.memo 비교 비용 > 리렌더 비용 → 오히려 악화
❌ 여러 변경 동시 적용
"인덱스 추가 + 캐싱 + 가상 스크롤 한 번에 적용"
→ 3.2초 개선 (좋아 보임)
→ 실제로는 캐싱이 -100ms 악화시켰으나 발견 불가
❌ 측정 환경 불일치
Before: 프로덕션 DB (10만 건)
After: 로컬 DB (100건)
→ "90% 개선!" → 거짓 양성
❌ 충분한 반복 측정 없이 판단
1회 측정: 2,100ms → "개선됨!"
3회 평균: 2,800ms → 오차 범위였음
→ 최소 3회 이상 반복 측정하여 평균 사용
일반적 개선 패턴 (참고)
| 병목 유형 | 개선 패턴 | 기대 효과 |
|---|---|---|
| DB 풀스캔 | 적절한 인덱스 추가 | 10x~100x |
| N+1 쿼리 | JOIN 또는 배치 쿼리로 변환 | 5x~50x |
| 대량 DOM 렌더 | 가상 스크롤 (react-window 등) | 5x~20x |
| 불필요 리렌더 | React.memo + 상태 분리 | 2x~5x |
| 대용량 번들 | 코드 스플리팅 + lazy load | 2x~5x |
| 동기 API 호출 | Promise.all 병렬화 | 2x~3x |
| 미압축 전송 | gzip/brotli 압축 | 1.5x~3x |
| 반복 연산 | 메모이제이션/캐싱 | 상황에 따라 다름 |
이 표는 참고용이며, 반드시 측정을 통해 실제 효과를 확인해야 한다.
Weekly Installs
1
Repository
doyoonear/skill…d-agentsFirst Seen
10 days ago
Security Audits
Installed on
amp1
cline1
openclaw1
opencode1
cursor1
kimi-cli1