Verify performance implications were considered and no obvious anti-patterns exist. Issues result in WARNINGS.
"Code that works is step one. Code that scales is step two."
This gate catches performance anti-patterns before they cause problems. The focus is on obvious issues, not micro-optimizations.
"What happens when there are 10,000 items? 1,000,000?"
Looking for:
"How many database queries does this operation make?"
Looking for:
"When this state changes, what components re-render?"
Looking for:
โ
PERFORMANCE GATE: PASSED
Performance considerations look good:
- Data fetching is efficient
- No obvious N+1 patterns
- Appropriate pagination in place
Moving to the next gate...
โ ๏ธ PERFORMANCE GATE: WARNING
Found [X] performance concerns:
**Issue 1: [N+1 Query / Inefficient Loop]**
Location: `file.ts:42`
Question: "This makes [N] queries. Can we batch into 1?"
**Issue 2: [Missing Pagination]**
Location: `file.ts:88`
Question: "What happens with 100,000 records?"
**Issue 3: [Expensive Render]**
Location: `Component.tsx:15`
Question: "Does this need to recalculate on every render?"
These may not matter now, but will become problems as the app grows.
โ const users = await User.findAll();
for (const user of users) {
user.posts = await Post.findByUserId(user.id);
}
// 1 + N queries!
โ
const users = await User.findAll({
include: [{ model: Post }]
});
// 1 query with JOIN
โ // Returns 10,000 users with 50 fields each
GET /api/users
โ
// Paginated with only needed fields
GET /api/users?page=1&limit=20&fields=id,name,email
โ 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>;
}
โ function Parent() {
return <Child onClick={() => doSomething()} />;
// New function every render โ Child re-renders
}
โ
function Parent() {
const handleClick = useCallback(() => doSomething(), []);
return <Child onClick={handleClick} />;
}
โ useEffect(() => {
const interval = setInterval(fetchData, 5000);
// Memory leak! Runs forever
}, []);
โ
useEffect(() => {
const interval = setInterval(fetchData, 5000);
return () => clearInterval(interval);
}, []);
Instead of pointing out the fix, ask:
| Pattern | Complexity | 10,000 items | Concern Level |
|---|---|---|---|
| Map lookup | O(1) | 1 op | Fine |
| Single loop | O(n) | 10,000 ops | Usually fine |
| Nested loop | O(nยฒ) | 100M ops | Warning |
| Triple loop | O(nยณ) | 1T ops | Critical |
| Flag | Question | Why |
|---|---|---|
| Query in a loop | "Can we batch?" | N+1 problem |
| No pagination | "What at scale?" | Memory/time explosion |
| SELECT * | "Need all fields?" | Wasted bandwidth |
| setInterval no cleanup | "What clears this?" | Memory leak |
| Inline object/function in JSX | "New reference?" | Unnecessary re-renders |
| Array.sort() in render | "Cached?" | Runs every render |
Not everything needs optimization:
for vs forEachThe gate is about catching obvious issues, not micro-optimization.