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.
"Premature optimization is the root of all evil, but mature ignorance is worse."
Activate this skill when reviewing:
❌ 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
});
❌ function Parent() {
const handleClick = () => {}; // New function every render
return <Child onClick={handleClick} />;
}
✅ function Parent() {
const handleClick = useCallback(() => {}, []);
return <Child onClick={handleClick} />;
}
❌ 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>;
}
❌ GET /api/users → returns 10,000 users with all fields
✅ GET /api/users?page=1&limit=20&fields=id,name,email
❌ useEffect(() => {
const interval = setInterval(fetchData, 5000);
// No cleanup! Runs forever.
}, []);
✅ useEffect(() => {
const interval = setInterval(fetchData, 5000);
return () => clearInterval(interval);
}, []);
Ask the junior these questions instead of giving answers:
| 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 |
| 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 |
| 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?" |