Instalar com Codex ou Claude Copie este prompt, cole no Codex, Claude ou outro assistente e deixe que ele revise a página da skill e instale para você.
Um comando direto ignora o prompt de revisão. Verifique a origem antes de executá-lo.
Find the actual bottleneck before optimizing. This skill applies systematic profiling methodology to identify where time and resources are being spent, then provides targeted optimizations ranked by impact. The cardinal rule: measure first, optimize second.
Key Concepts
The Performance Budget
Define targets before measuring:
Web Vitals Targets:
LCP (Largest Contentful Paint) < 2.5s
FID (First Input Delay) < 100ms
CLS (Cumulative Layout Shift) < 0.1
TTFB (Time to First Byte) < 800ms
INP (Interaction to Next Paint) < 200ms
API Targets:
p50 latency < 100ms
p95 latency < 500ms
p99 latency < 1000ms
Error rate < 0.1%
Bundle Targets:
Initial JS < 100KB gzipped
Total JS < 300KB gzipped
First load < 200KB transferred
-- PostgreSQL: Analyze query plan
EXPLAIN (ANALYZE, BUFFERS, FORMAT TEXT)
SELECT u.*, COUNT(p.id) as post_count
FROM users u
LEFTJOIN posts p ON p.user_id = u.id
WHERE u.created_at >'2024-01-01'GROUPBY u.id
ORDERBY post_count DESC
LIMIT 20;
-- Look for:-- Seq Scan on large tables → needs index-- Nested Loop with high row count → consider join strategy-- Sort with high memory → add index for ORDER BY-- Actual rows >> Estimated rows → stale statistics (run ANALYZE)
Phase 2: Identify Bottleneck
The 80/20 Rule: 80% of time is spent in 20% of code. Find that 20%.
Profiling Checklist:
1. Where is wall-clock time spent?
- CPU computation
- Waiting for I/O (DB, network, disk)
- Garbage collection pauses
2. What is the call frequency?
- Called once but slow → optimize the function
- Called 1000x but fast → reduce call count (batching, caching)
3. What is the data volume?
- Processing too much data → paginate, filter earlier
- Transferring too much → compress, select specific fields
4. Where are allocations?
- Creating objects in hot loops → pre-allocate, reuse
- Large strings/arrays → streaming, chunking
Phase 3: Optimize (Targeted)
CPU Optimization Patterns
// BEFORE: O(n^2) nested lookupconst enriched = users.map(user => ({
...user,
posts: posts.filter(p => p.userId === user.id), // O(n) for each user
}));
// AFTER: O(n) with pre-indexed lookupconst postsByUser = newMap<string, Post[]>();
for (const post of posts) {
const existing = postsByUser.get(post.userId) ?? [];
existing.push(post);
postsByUser.set(post.userId, existing);
}
const enriched = users.map(user => ({
...user,
posts: postsByUser.get(user.id) ?? [],
}));
-- BEFORE: N+1 query (1 query per user for their posts)-- ORM generates: SELECT * FROM posts WHERE user_id = $1 (repeated N times)-- AFTER: Single query with JOINSELECT u.id, u.name, p.id as post_id, p.title
FROM users u
LEFTJOIN posts p ON p.user_id = u.id
WHERE u.active =true;
-- Add missing indexesCREATE INDEX CONCURRENTLY idx_posts_user_id ON posts(user_id);
CREATE INDEX CONCURRENTLY idx_users_active ON users(active) WHERE active =true;
-- Use covering index to avoid table lookupCREATE INDEX idx_posts_user_id_covering
ON posts(user_id) INCLUDE (title, created_at);