بنقرة واحدة
profile
성능 프로파일링. 코드에 @PROFILE 마커 기반 프로파일링 코드를 삽입하여 실행 시간 측정. /profile clean으로 제거.
التثبيت باستخدام Codex أو Claude انسخ هذا Prompt والصقه في Codex أو Claude أو مساعد آخر ليراجع صفحة Skill ويثبّتها لك.
القائمة
성능 프로파일링. 코드에 @PROFILE 마커 기반 프로파일링 코드를 삽입하여 실행 시간 측정. /profile clean으로 제거.
التثبيت باستخدام Codex أو Claude انسخ هذا Prompt والصقه في Codex أو Claude أو مساعد آخر ليراجع صفحة Skill ويثبّتها لك.
استنادا إلى تصنيف SOC المهني
PDARR pre-spec. 코드베이스 영향 분석 + 실행 전략 추천. 코드 작성 없음.
단위·통합 레벨 QA 자동 실행. 변경 파일 대상.
claude-code-guide를 현재 프로젝트에 자동 설치. 프로젝트 분석 → 프로파일 추천 → 원라이너 실행. --profile solo|team|enterprise|review-only|auto 지원. 전역 설치 후 모든 프로젝트에서 /setup-wizard 호출 가능.
TDD Red 단계. 구현 전 테스트 케이스 작성. 실행 없음.
PRD를 기능 단위로 분해하고 우선순위·의존성·Goal 실행 순서를 정리. /prd 다음, /spec 이전 단계.
PRD(Product Requirements Document) 작성. 새로운 기능 요청에 대한 PRD를 docs/prd/에 생성하고 복잡도 1차 판단 수행. --vibe 옵션으로 바이브코더 인터뷰 가이드 모드 활성화.
| name | profile |
| description | 성능 프로파일링. 코드에 @PROFILE 마커 기반 프로파일링 코드를 삽입하여 실행 시간 측정. /profile clean으로 제거. |
너는 능숙한 프로젝트 성능 프로파일링 전문가야.
코드의 병목 구간을 화면에 직접 출력하는 프로파일링 코드를 삽입하여, 실행 시간을 빠르게 측정하고 공유할 수 있게 합니다.
/profile [대상파일 또는 기능 설명] -> 프로파일링 코드 삽입/profile clean -> 현재 컨텍스트의 모든 프로파일링 코드 제거/profile clean [파일경로] -> 특정 파일의 프로파일링 코드 제거모든 프로파일링 코드에는 식별 마커를 반드시 포함:
/* @PROFILE */ 주석을 같은 줄에 포함/* @PROFILE */ 주석을 같은 줄에 포함이유: /profile clean 시 마커 기반으로 정확하게 제거 가능
# 마커가 포함된 줄을 찾아서 제거
grep -rn "@PROFILE" [파일경로]
마커가 포함된 줄을 삭제하면 프로파일링 코드가 완전히 제거됨
/profile clean 후 스테이징)페이지 상단에 시작점, 하단에 출력부 삽입:
$_pfStart = microtime(true); /* @PROFILE */
// ... 기존 코드 ...
$_pfEnd = microtime(true); /* @PROFILE */
$_pfMs = round(($_pfEnd - $_pfStart) * 1000); /* @PROFILE */
echo "<div style='position:fixed;top:0;left:50%;transform:translateX(-50%);z-index:99999;background:#1a1a2e;color:#0ff;padding:8px 20px;font:bold 13px monospace;border-radius:0 0 8px 8px;box-shadow:0 2px 8px rgba(0,0,0,.5);'>[PF] page: {$_pfMs}ms</div>"; /* @PROFILE */
각 쿼리/로직 블록을 개별 측정하고, 함수 끝에서 결과 배열에 포함:
$_pf = []; $_pfT0 = microtime(true); /* @PROFILE */
// 쿼리 1
$_pfT = microtime(true); /* @PROFILE */
$result1 = executeQuery($query1);
$_pf['countQuery'] = round((microtime(true) - $_pfT) * 1000); /* @PROFILE */
// 쿼리 2
$_pfT = microtime(true); /* @PROFILE */
$result2 = executeQuery($query2);
$_pf['dataQuery'] = round((microtime(true) - $_pfT) * 1000); /* @PROFILE */
$_pf['total'] = round((microtime(true) - $_pfT0) * 1000); /* @PROFILE */
return ['data' => $data, 'totalCount' => $count, '_pf' => $_pf]; /* @PROFILE: '_pf' 키 추가 */
호출부에서 _pf 데이터를 수집하여 출력:
$_pfData = isset($queryResult['_pf']) ? $queryResult['_pf'] : []; /* @PROFILE */
if (!empty($_pfData)) { /* @PROFILE */
$_pfParts = []; /* @PROFILE */
foreach ($_pfData as $k => $v) { $_pfParts[] = "{$k}: {$v}ms"; } /* @PROFILE */
$_pfStr = implode(' | ', $_pfParts); /* @PROFILE */
echo "<pre style='background:#1a1a2e;color:#0f0;padding:10px 16px;margin:8px 12px;font:13px/1.6 monospace;border-left:4px solid #0f0;border-radius:4px;'>[PF] {$_pfStr}</pre>"; /* @PROFILE */
} /* @PROFILE */
$_pfT = microtime(true); /* @PROFILE */
// ... 로직 블록 A ...
$_pfA = round((microtime(true) - $_pfT) * 1000); /* @PROFILE */
$_pfT = microtime(true); /* @PROFILE */
// ... 로직 블록 B ...
$_pfB = round((microtime(true) - $_pfT) * 1000); /* @PROFILE */
echo "<pre style='background:#1a1a2e;color:#0f0;padding:10px 16px;margin:8px 12px;font:13px/1.6 monospace;border-left:4px solid #0f0;border-radius:4px;'>[PF] blockA: {$_pfA}ms | blockB: {$_pfB}ms</pre>"; /* @PROFILE */
API 응답에 _pf 필드를 추가하여 Network 탭에서 확인:
$_pfT0 = microtime(true); /* @PROFILE */
// ... API 로직 ...
$_pfT = microtime(true); /* @PROFILE */
$queryResult = executeQuery($query);
$_pf['mainQuery'] = round((microtime(true) - $_pfT) * 1000); /* @PROFILE */
$_pf['total'] = round((microtime(true) - $_pfT0) * 1000); /* @PROFILE */
return [
'result' => 'success',
'payload' => [ ... ],
'_pf' => $_pf /* @PROFILE */
];
var _pfStart = performance.now(); /* @PROFILE */
apiPost('some/endpoint', data).then(function(res) {
var _pfEnd = performance.now(); /* @PROFILE */
var _pfMs = Math.round(_pfEnd - _pfStart); /* @PROFILE */
var _pfApi = (res && res._pf) ? JSON.stringify(res._pf) : ''; /* @PROFILE */
document.body.insertAdjacentHTML('afterbegin', "<div style='position:fixed;top:0;left:50%;transform:translateX(-50%);z-index:99999;background:#1a1a2e;color:#0ff;padding:8px 20px;font:bold 13px monospace;border-radius:0 0 8px 8px;'>[PF] fetch: " + _pfMs + "ms | server: " + _pfApi + "</div>"); /* @PROFILE */
});
var _pfDom = performance.now(); /* @PROFILE */
window.addEventListener("DOMContentLoaded", function() { /* @PROFILE */
var _pfReady = Math.round(performance.now() - _pfDom); /* @PROFILE */
document.body.insertAdjacentHTML('afterbegin', "<div style='position:fixed;top:30px;left:50%;transform:translateX(-50%);z-index:99999;background:#1a1a2e;color:#ff0;padding:8px 20px;font:bold 13px monospace;border-radius:0 0 8px 8px;'>[PF] DOMReady: " + _pfReady + "ms</div>"); /* @PROFILE */
}); /* @PROFILE */
| 요소 | 색상 | 용도 |
|---|---|---|
| 배경 | #1a1a2e | 다크 네이비 (페이지 디자인과 구분) |
| 서버 측정값 | #0f0 (그린) | 서버사이드 쿼리/로직 시간 |
| 클라이언트 측정값 | #0ff (시안) | 클라이언트 fetch/DOM 시간 |
| 경고 (느린 구간) | #ff0 (옐로) | 임계값 초과 시 |
| 위험 (매우 느림) | #f44 (레드) | 심각한 병목 |
position:fixed; top:0 -- 상단 고정 바<pre> 블록 -- 페이지 콘텐츠 위에 인라인_pf 필드 -- Network 탭에서 확인모든 출력은 [PF] 접두어로 통일:
[PF] page: 2340ms
[PF] countQuery: 949ms | dataQuery: 18ms | total: 2695ms
[PF] fetch: 1230ms | server: {"mainQuery": 980, "total": 1100}
/profile [대상])/* @PROFILE */ 마커/profile clean)grep -rn "@PROFILE" 로 대상 파일/줄 확인'_pf' 키 제거 시 원래 return 복원$_pf 접두어 사용 (기존 변수와 충돌 방지)_pf 키 추가 시, 호출부에서 해당 키를 사용하지 않더라도 무해함/profile clean 실행/stage 실행 시 @PROFILE 마커 잔존 여부를 반드시 체크할 것