multiAI Summary Pending

performance-fundamentals

Auto-invoke when reviewing loops, data fetching, rendering, database queries, or resource-intensive operations. Identifies N+1 queries, unnecessary re-renders, memory leaks, and scalability issues.

231 stars

Installation

Claude Code / Cursor / Codex

$curl -o ~/.claude/skills/performance-fundamentals/SKILL.md --create-dirs "https://raw.githubusercontent.com/aiskillstore/marketplace/main/skills/danielpodolsky/performance-fundamentals/SKILL.md"

Manual Installation

  1. Download SKILL.md from GitHub
  2. Place it in .claude/skills/performance-fundamentals/SKILL.md inside your project
  3. Restart your AI agent — it will auto-discover the skill

How performance-fundamentals Compares

Feature / Agentperformance-fundamentalsStandard Approach
Platform SupportmultiLimited / Varies
Context Awareness High Baseline
Installation ComplexityUnknownN/A

Frequently Asked Questions

What does this skill do?

Auto-invoke when reviewing loops, data fetching, rendering, database queries, or resource-intensive operations. Identifies N+1 queries, unnecessary re-renders, memory leaks, and scalability issues.

Which AI agents support this skill?

This skill is compatible with multi.

Where can I find the source code?

You can find the source code on GitHub using the link provided at the top of the page.

SKILL.md Source

# Performance Fundamentals Review

> "Premature optimization is the root of all evil, but mature ignorance is worse."

## When to Apply

Activate this skill when reviewing:
- Database queries (especially in loops)
- React/Vue render logic
- API response payloads
- Data transformations
- File operations
- Caching decisions

---

## Review Checklist

### Database Performance

- [ ] **No N+1 queries**: Are related records fetched in bulk, not loops?
- [ ] **Indexes**: Are frequently queried fields indexed?
- [ ] **Pagination**: Do list endpoints paginate results?
- [ ] **Select only needed fields**: Are we fetching entire records unnecessarily?

### Frontend Performance

- [ ] **Memoization**: Are expensive computations cached?
- [ ] **Re-render prevention**: Will state changes cause unnecessary re-renders?
- [ ] **Bundle size**: Are heavy libraries lazy-loaded?
- [ ] **Image optimization**: Are images properly sized and formatted?

### API Performance

- [ ] **Response size**: Is the payload minimal?
- [ ] **Compression**: Is gzip/brotli enabled?
- [ ] **Caching headers**: Are cacheable responses marked?
- [ ] **Async processing**: Are slow operations queued?

### Memory & Resources

- [ ] **Cleanup**: Are subscriptions/timers cleaned up?
- [ ] **Memory leaks**: Are event listeners removed?
- [ ] **Connection pooling**: Are DB connections reused?

---

## Common Mistakes (Anti-Patterns)

### 1. The N+1 Query Problem
```
❌ const users = await User.findAll();
   for (const user of users) {
     user.posts = await Post.findByUserId(user.id); // N queries!
   }

✅ const users = await User.findAll({
     include: [{ model: Post }] // 1 query with JOIN
   });
```

### 2. Unnecessary Re-renders
```
❌ function Parent() {
     const handleClick = () => {}; // New function every render
     return <Child onClick={handleClick} />;
   }

✅ function Parent() {
     const handleClick = useCallback(() => {}, []);
     return <Child onClick={handleClick} />;
   }
```

### 3. Computing in Render
```
❌ function UserList({ users }) {
     // Runs on every render
     const sorted = users.sort((a, b) => a.name.localeCompare(b.name));
     return <ul>{sorted.map(...)}</ul>;
   }

✅ function UserList({ users }) {
     const sorted = useMemo(
       () => [...users].sort((a, b) => a.name.localeCompare(b.name)),
       [users]
     );
     return <ul>{sorted.map(...)}</ul>;
   }
```

### 4. Fetching Everything
```
❌ GET /api/users → returns 10,000 users with all fields

✅ GET /api/users?page=1&limit=20&fields=id,name,email
```

### 5. Missing Cleanup
```
❌ useEffect(() => {
     const interval = setInterval(fetchData, 5000);
     // No cleanup! Runs forever.
   }, []);

✅ useEffect(() => {
     const interval = setInterval(fetchData, 5000);
     return () => clearInterval(interval);
   }, []);
```

---

## Socratic Questions

Ask the junior these questions instead of giving answers:

1. **Scale**: "What happens when there are 10,000 items? 1,000,000?"
2. **Queries**: "How many database queries does this operation make?"
3. **Re-renders**: "When this state changes, what components re-render?"
4. **Memory**: "Is anything holding a reference after it's no longer needed?"
5. **Payload**: "Does the client need ALL of this data?"

---

## Big O Quick Reference

| Pattern | Complexity | Example | At 10,000 items |
|---------|------------|---------|-----------------|
| Direct lookup | O(1) | `map.get(key)` | 1 op |
| Single loop | O(n) | `array.find()` | 10,000 ops |
| Nested loops | O(n²) | `for i { for j }` | 100,000,000 ops |
| Sort | O(n log n) | `array.sort()` | ~130,000 ops |

---

## Performance Targets

| Metric | Target | Measure With |
|--------|--------|--------------|
| Time to First Byte (TTFB) | < 600ms | DevTools Network |
| Largest Contentful Paint (LCP) | < 2.5s | Lighthouse |
| First Input Delay (FID) | < 100ms | Lighthouse |
| Cumulative Layout Shift (CLS) | < 0.1 | Lighthouse |
| API Response Time | < 200ms (p95) | Server metrics |

---

## Red Flags to Call Out

| Flag | Question to Ask |
|------|-----------------|
| Query inside a loop | "Can we batch this into one query?" |
| No pagination | "What if there are 100,000 records?" |
| `SELECT *` | "Do we need all these fields?" |
| Large JSON in localStorage | "Will this slow down page load?" |
| Inline function in JSX | "Does this create a new function every render?" |
| setInterval without cleanup | "What clears this when the component unmounts?" |
| Synchronous file operations | "Should this be async?" |
| No loading states | "What does the user see while waiting?" |

---

## Quick Wins

1. **Add indexes** to frequently queried DB columns
2. **Paginate** all list endpoints
3. **Lazy load** below-the-fold content
4. **Compress** API responses
5. **Cache** expensive computations with useMemo
6. **Debounce** search inputs
7. **Virtualize** long lists (react-window)