Skip to content
Development
Skill

/performance

Reviews performance including N+1 queries, re-renders, scalability. Use when junior asks "is this performant", "will this scale", "too slow", or builds loops, large lists, pagination, caching.

From plugin
ownyourcode
27421 skills12 commands
Install
$ npx -y skills add DanielPodolsky/ownyourcode --skill performance --agent claude-code

How it fires

How this skill gets triggered: by you, by Claude, or both.

  • Fires itselfAuto-invocation. Claude auto-loads it when your prompt matches the work.Auto-invocation is when the right skill fires by itself at the right moment, driven by a FLOW.md router and a hook, instead of you invoking it by name. It is the difference between a skill being installed and a skill actually getting used.Read the full definition →
  • You can call itInvoke it directly when you want it.
  • Slash command/performance

Context preview

The summary Claude sees to decide when to auto-load this skill.

Reviews performance including N+1 queries, re-renders, scalability. Use when junior asks "is this performant", "will this scale", "too slow", or builds loops, large lists, pagination, caching.

SKILL.md

performance.SKILL.md
name: performance-fundamentals
description: Reviews performance including N+1 queries, re-renders, scalability. Use when junior asks "is this performant", "will this scale", "too slow", or builds loops, large lists, pagination, caching.

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)

Read more
Ships withownyourcode

Claude Code workflow for AI-mentored development. Work efficiently with Spec-Driven Development and the 6 Gates. Built to fight cognitive offloading — for developers using AI to grow and maintain ownership.

Get the whole plugin