performance-reviewer
>-
Works with
---
name: performance-reviewer
description: >-
license: Apache-2.0
---
# Performance Reviewer
## Overview
This skill analyzes code changes for performance regressions and optimization opportunities. It catches common issues like N+1 database queries, unnecessary re-renders in React components, missing database indexes, unoptimized loops, and bundle size increases before they reach production.
## Instructions
### Analyzing a Diff or PR
1. Get the diff: `git diff main...HEAD` or `git diff <base>...<head>`
2. For each changed file, evaluate against these performance categories:
**Database & Queries:**
- Look for queries inside loops (N+1 pattern)
- Check for missing `WHERE` clauses or full table scans
- Identify missing indexes on columns used in `WHERE`, `JOIN`, or `ORDER BY`
- Flag `SELECT *` when only specific columns are needed
- Watch for unbounded queries without `LIMIT`
**Frontend & Rendering:**
- React: Check for missing `useMemo`/`useCallback` on expensive computations passed as props
- Look for state updates that trigger unnecessary re-renders of large component trees
- Flag inline object/array creation in render (creates new reference every render)
- Check for large bundle imports (`import moment` → suggest `dayjs`)
**Algorithm & Data Structures:**
- Flag O(n²) or worse algorithms when O(n log n) alternatives exist
- Look for repeated array searches that should use a Set or Map
- Identify string concatenation in loops (suggest StringBuilder/join)
**Memory & Resources:**
- Check for missing cleanup in `useEffect` (event listeners, intervals, subscriptions)
- Look for growing arrays/objects that are never trimmed
- Flag missing connection pool limits or unclosed file handles
**Network & I/O:**
- Identify sequential API calls that could be parallelized (`Promise.all`)
- Check for missing pagination on list endpoints
- Flag missing caching for expensive or repeated operations
### Output Format
For each issue found, report:
- **File and line number**
- **Category** (Database, Frontend, Algorithm, Memory, Network)
- **Severity** (Critical, Warning, Info)
- **What's wrong** (specific description)
- **Suggested fix** (concrete code suggestion)
### Severity Guidelines
- **Critical**: Will cause visible degradation in production (N+1 in a loop, O(n²) on large datasets, memory leak)
- **Warning**: May cause issues at scale (missing index, unnecessary re-renders, sequential API calls)
- **Info**: Optimization opportunity, not urgent (bundle size suggestion, minor refactor)
## Examples
### Example 1: N+1 Query Detection
**Input diff:**
```python
# api/views.py
def list_orders(request):
orders = Order.objects.filter(user=request.user)
result = []
for order in orders:
items = OrderItem.objects.filter(order=order) # ← query per order
result.append({
"id": order.id,
"total": order.total,
"items": [{"name": i.product.name, "qty": i.quantity} for i in items]
})
return JsonResponse(result, safe=False)
```
**Output:**
```
🔴 Critical — Database N+1 Query
File: api/views.py:5-8
Issue: OrderItem query executes once per order, plus each i.product.name
triggers another query. For 50 orders with 3 items each = 201 queries.
Fix: Use select_related and prefetch_related:
orders = Order.objects.filter(user=request.user).prefetch_related(
Prefetch('items', queryset=OrderItem.objects.select_related('product'))
)
Result: Reduces to 3 queries regardless of order count.
```
### Example 2: React Re-render Issue
**Input diff:**
```jsx
function UserList({ users, onSelect }) {
return (
<div>
{users.map(user => (
<UserCard
key={user.id}
user={user}
style={{ padding: 16, margin: 8 }}
onClick={() => onSelect(user.id)}
/>
))}
</div>
);
}
```
**Output:**
```
🟡 Warning — Unnecessary Re-renders
File: components/UserList.jsx:6-7
Issue: Inline object `style={{ padding: 16, margin: 8 }}` and arrow function
`() => onSelect(user.id)` create new references every render, causing
all UserCard components to re-render even when users haven't changed.
Fix:
const cardStyle = useMemo(() => ({ padding: 16, margin: 8 }), []);
const handleClick = useCallback((id) => onSelect(id), [onSelect]);
// Then: style={cardStyle} onClick={() => handleClick(user.id)}
Impact: With 100+ users, prevents ~100 unnecessary DOM diffing operations per parent render.
```
## Guidelines
- Focus on issues introduced by the diff, not pre-existing problems
- Prioritize Critical issues — don't bury them in a list of Info suggestions
- Always provide concrete fix suggestions, not just "optimize this"
- Consider the scale: an O(n²) loop on a 5-element array is fine; on user-generated data it's not
- When suggesting caching, specify what to cache and invalidation strategy
- Don't flag micro-optimizations that harm readability for negligible gainMore Code Review skills
pr-to-video
heygen-com/hyperframes
Turn a GitHub pull request (a PR URL, owner/repo#N, or 'this PR' in a checked-out repo) into a code-change explainer video — changelog, feature reveal, fix, or refactor walkthrough built from the diff, commits, and files: the input is a code change, not a website. Not a product promo (/product-launch-video) or a no-PR topic explainer (/faceless-explainer). Unclear → /hyperframes.
receiving-code-review
obra/superpowers
Use when receiving code review feedback, before implementing suggestions, especially if feedback seems unclear or technically questionable - requires technical rigor and verification, not performative agreement or blind implementation
public-relations
coreyhaines31/marketingskills
When the user wants help with public relations, earned media, press coverage, journalist outreach, or media strategy (not pull requests). Also use when the user mentions 'PR,' 'public relations,' 'press,' 'press release,' 'press coverage,' 'media outreach,' 'pitch a journalist,' 'get featured,' 'media list,' 'media kit,' 'press kit,' 'newsjacking,' 'news hijack,' 'HARO,' 'Qwoted,' 'Featured,' 'Help A Reporter,' 'reporter request,' 'tech press,' 'TechCrunch,' 'earned media,' 'thought leadership placement,' 'op-ed,' 'guest article,' 'press contacts,' 'podcast prep,' 'going on a podcast,' 'podcast guest,' 'prep me for this podcast,' or 'how do I get press.' Use this for earned media work — finding journalists, pitching stories, newsjacking, prepping podcast appearances, and responding to press requests. For startup/SaaS/AI directory submissions, see directory-submissions. For product launches, see launch. For social-media engagement, see social. For cold-email outreach to prospects, see cold-email.

