dot_claude/skills/performance-profiling/SKILL.md
Use when investigating performance issues, before attempting any optimization - four-phase methodology (baseline measurement, bottleneck profiling, complexity analysis, targeted optimization) that ensures data-driven decisions over gut-feel tuning | パフォーマンスの問題を調査する際、最適化を試みる前に使用 - 4フェーズ手法(ベースライン測定、ボトルネックプロファイリング、計算量分析、的を絞った最適化)により、直感的なチューニングではなくデータに基づく判断を保証
npx skillsauth add lv416e/dotfiles performance-profilingInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
Optimizing without measuring is guessing. Guessing wastes time and often makes things worse.
Core principle: ALWAYS measure before optimizing. Intuition about performance is wrong more often than right.
Violating the letter of this process is violating the spirit of performance engineering.
MEASURE FIRST, OPTIMIZE SECOND - NO PREMATURE OPTIMIZATION WITHOUT PROFILING DATA
If you haven't profiled it, you cannot optimize it. Hunches are not data.
Use for ANY performance concern:
Use this ESPECIALLY when:
Don't skip when:
You MUST complete each phase before proceeding to the next.
BEFORE changing ANY code:
Define What "Fast Enough" Means
Measure Current Performance
# HTTP endpoints
hey -n 1000 -c 50 https://api.example.com/endpoint
# Application benchmarks
hyperfine --warmup 3 'command-to-benchmark'
# Database queries
EXPLAIN ANALYZE SELECT ...;
Record the Baseline
Reproduce Under Realistic Conditions
No baseline? No optimization. Period.
Find where time is actually spent:
CPU Profiling
# Node.js
node --prof app.js
node --prof-process isolate-*.log
# Python
python -m cProfile -o output.prof script.py
# Go
go tool pprof http://localhost:6060/debug/pprof/profile
Generate Flame Graphs
Memory Profiling
# Node.js
node --inspect app.js
# Chrome DevTools → Memory → Heap Snapshot
# Python
tracemalloc.start()
# ... run code ...
snapshot = tracemalloc.take_snapshot()
I/O and Network Profiling
Identify the Actual Bottleneck
| Bottleneck Type | Symptoms | Tools | |----------------|----------|-------| | CPU-bound | High CPU%, slow computation | Profiler, flame graph | | Memory-bound | High memory, GC pauses, swapping | Heap profiler, memory tracker | | I/O-bound | Low CPU%, waiting on disk/network | Tracing, query logs | | Concurrency | Lock contention, thread starvation | Thread profiler, lock analysis |
Key insight: Most "slow" applications are I/O-bound, not CPU-bound. Don't optimize CPU when you're waiting on the database.
Before micro-optimizing, check the algorithm:
Big-O Review
Common Hidden Complexity
<Bad> ```typescript // O(n*m) - linear search inside loop for (const user of users) { const role = roles.find(r => r.userId === user.id); } ``` </Bad> <Good> ```typescript // O(n+m) - build lookup map first const roleMap = new Map(roles.map(r => [r.userId, r])); for (const user of users) { const role = roleMap.get(user.id); } ``` </Good>Database Query Analysis
-- Always EXPLAIN before optimizing
EXPLAIN ANALYZE
SELECT u.*, COUNT(o.id)
FROM users u
LEFT JOIN orders o ON o.user_id = u.id
GROUP BY u.id;
N+1 Query Detection
<Bad> ```typescript // 1 query for users + N queries for orders const users = await db.query('SELECT * FROM users'); for (const user of users) { user.orders = await db.query('SELECT * FROM orders WHERE user_id = ?', [user.id]); } ``` </Bad> <Good> ```typescript // 2 queries total regardless of user count const users = await db.query('SELECT * FROM users'); const orders = await db.query('SELECT * FROM orders WHERE user_id = ANY(?)', [userIds]); const ordersByUser = groupBy(orders, 'user_id'); ``` </Good>Optimize only what profiling identified:
Write a Benchmark First
// Before optimizing, capture current performance
bench('current implementation', () => {
currentFunction(testData);
});
bench('optimized implementation', () => {
optimizedFunction(testData);
});
Make ONE Change at a Time
Verify Against Baseline
Frontend-Specific Optimization
Memory Leak Resolution
Before any production deployment of performance-sensitive changes:
# k6 example
k6 run --vus 50 --duration 5m load-test.js
# Artillery example
artillery run load-test.yml
If you catch yourself thinking:
ALL of these mean: STOP. Return to Phase 1.
| Excuse | Reality | |--------|---------| | "Obviously slow, don't need to measure" | Obvious intuitions are wrong 70% of the time. Measure. | | "Just add caching" | Caching without understanding causes stale data bugs and hides real issues. | | "Rewrite in a faster language" | Algorithm matters more than language. O(n^2) in Rust is still O(n^2). | | "Micro-benchmarks show improvement" | Micro-benchmarks don't reflect real workload. Measure end-to-end. | | "Profiler is too hard to set up" | 10 minutes to set up profiler vs. hours guessing. Set it up. | | "It's just one query" | One query called 10,000 times is 10,000 queries. Measure frequency. | | "Increase the timeout" | Timeouts mask real problems. Find why it's slow. | | "Premature optimization, skip it" | Measuring is not optimizing. Always measure. Decide after. | | "Add an index, can't hurt" | Wrong indexes slow writes. EXPLAIN first. | | "Optimize later when it matters" | Launching without baseline means you can't measure regression. |
| Anti-Pattern | Consequence | Correct Approach | |-------------|-------------|-----------------| | Optimizing without measuring | Wrong target, wasted effort, new bugs | Profile first, optimize the actual bottleneck | | Micro-optimizing cold paths | No user-visible improvement | Focus on hot paths identified by profiling | | Premature caching | Stale data, cache invalidation bugs, complexity | Fix the root cause; cache only after measuring | | Ignoring algorithmic complexity | Linear "optimization" on exponential problem | Fix the algorithm before tuning constants | | Optimizing in isolation | Benchmark looks good, production doesn't improve | Test under realistic load and data | | Stacking multiple optimizations | Can't tell which one helped (or hurt) | One change at a time, measure each |
| Phase | Key Activities | Success Criteria | |-------|---------------|------------------| | 1. Baseline | Define targets, measure current state, record numbers | Concrete metrics documented | | 2. Profile | CPU/memory/I/O profiling, flame graphs, identify bottleneck | Know WHERE time is spent | | 3. Complexity | Big-O review, N+1 detection, EXPLAIN queries | Algorithmic issues found or ruled out | | 4. Optimize | Benchmark, single change, measure, compare to baseline | Meets target or next bottleneck identified |
Before marking performance work complete:
Can't check all boxes? You're not done.
This skill requires using:
Complementary skills:
No profiling data → no optimization
No baseline → no comparison
No target → no "done"
Measure. Profile. Optimize. Verify. In that order. Always.
development
Use this skill any time a spreadsheet file is the primary input or output. This means any task where the user wants to: open, read, edit, or fix an existing .xlsx, .xlsm, .csv, or .tsv file (e.g., adding columns, computing formulas, formatting, charting, cleaning messy data); create a new spreadsheet from scratch or from other data sources; or convert between tabular file formats. Trigger especially when the user references a spreadsheet file by name or path — even casually (like "the xlsx in my downloads") — and wants something done to it or produced from it. Also trigger for cleaning or restructuring messy tabular data files (malformed rows, misplaced headers, junk data) into proper spreadsheets. The deliverable must be a spreadsheet file. Do NOT trigger when the primary deliverable is a Word document, HTML report, standalone Python script, database pipeline, or Google Sheets API integration, even if tabular data is involved.
testing
Use when creating new skills, editing existing skills, or verifying skills work before deployment - applies TDD to process documentation by testing with subagents before writing, iterating until bulletproof against rationalization | 新しいスキルの作成、既存スキルの編集、またはデプロイ前にスキルが機能するか検証する際に使用 - プロセスドキュメントにTDDを適用し、記述前にサブエージェントでテストし、合理化に対して堅牢になるまで反復
development
Use when design is complete and you need detailed implementation tasks for engineers with zero codebase context - creates comprehensive implementation plans with exact file paths, complete code examples, and verification steps assuming engineer has minimal domain knowledge | 設計が完了し、コードベースの知識がゼロのエンジニア向けに詳細な実装タスクが必要な場合に使用 - 正確なファイルパス、完全なコード例、検証ステップを含む包括的な実装計画を作成。エンジニアの領域知識が最小限であることを前提
tools
Toolkit for interacting with and testing local web applications using Playwright. Supports verifying frontend functionality, debugging UI behavior, capturing browser screenshots, and viewing browser logs.