Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
241b770
Add checkReactCompilerOptimization tool
mateuuszzzzz Dec 8, 2025
171c9c6
Improve PERF-4 organisation in prompt and remove reason key from chec…
mateuuszzzzz Dec 8, 2025
e156e7a
Improve object example
mateuuszzzzz Dec 8, 2025
758dfd1
Improve PERF-4 examples
mateuuszzzzz Dec 8, 2025
9c2b316
Merge branch 'main' into add-react-compiler-context-to-ai-reviewer
mateuuszzzzz Dec 11, 2025
9337cc7
Add artifact upload for Claude execution report
mateuuszzzzz Dec 15, 2025
619bf85
Update PERF-4 rules
mateuuszzzzz Dec 15, 2025
95fd884
install typescript
mateuuszzzzz Dec 15, 2025
5b04815
Update react compiler script
mateuuszzzzz Dec 15, 2025
de17e9e
Make sure we take custom memo comparators into consideration
mateuuszzzzz Dec 15, 2025
a0ec141
Adjust how we find component name
mateuuszzzzz Dec 15, 2025
09ecea2
Introduce improvements to script output format
mateuuszzzzz Dec 16, 2025
36b014d
Explicitly state that script is available in PTH
mateuuszzzzz Dec 16, 2025
ac2561b
Force agent to use checkReactCompilerOptimization
mateuuszzzzz Dec 16, 2025
f454c49
Handle new files in PR
mateuuszzzzz Dec 16, 2025
2f993cc
refactor(PERF-4): make rules more compact and fix decision flow
mateuuszzzzz Dec 16, 2025
4ee8f1b
feat(PERF-4): add sourcePath to script output for custom comparator c…
mateuuszzzzz Dec 16, 2025
0d36973
fix(PERF-4): make script requirement explicit for EVERY .tsx file
mateuuszzzzz Dec 16, 2025
46ec7f6
Include arrays in PERF-4
mateuuszzzzz Dec 16, 2025
e06c79b
Add spread props example
mateuuszzzzz Dec 16, 2025
2e9882b
Make intensions with spread props example more explicit
mateuuszzzzz Dec 16, 2025
71b3bbd
Forbid to use not specified tools
mateuuszzzzz Dec 16, 2025
b3208cf
Revert "Forbid to use not specified tools"
mateuuszzzzz Dec 16, 2025
58612b0
Revert "Add artifact upload for Claude execution report"
mateuuszzzzz Dec 16, 2025
9902166
Fix eslint
mateuuszzzzz Dec 19, 2025
f4d80e7
Use ts instead of js and remove shell wrapper
mateuuszzzzz Dec 22, 2025
8d79b02
Update Claude instructions
mateuuszzzzz Dec 22, 2025
4e49cd9
Add information that script is available in PATH
mateuuszzzzz Dec 22, 2025
520b36b
Fix shebang
mateuuszzzzz Dec 22, 2025
3e787a2
Reference ts-node via npx in shebang
mateuuszzzzz Dec 22, 2025
a7d9e1d
Adjust prompt
mateuuszzzzz Dec 22, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
78 changes: 63 additions & 15 deletions .claude/agents/code-inline-reviewer.md
Original file line number Diff line number Diff line change
Expand Up @@ -143,31 +143,79 @@ const [personalDetails] = useOnyx(ONYXKEYS.PERSONAL_DETAILS_LIST);

---

### [PERF-4] Memoize objects and functions passed as props
### [PERF-4] Memoize objects (including arrays) and functions passed as props

- **Search patterns**: `useMemo`, `useCallback`, and prop passing patterns
- **Search patterns**: `prop={{`, `prop={[`, `={() =>`, `prop={variable}` (where variable is non-memoized object/function)

- **Condition**: Objects and functions passed as props should be properly memoized or simplified to primitive values to prevent unnecessary re-renders.
- **Reasoning**: React uses referential equality to determine if props changed. New object/function instances on every render trigger unnecessary re-renders of child components, even when the actual data hasn't changed. Memoization preserves referential stability.
- **Applies ONLY to**: Objects (including arrays)/functions passed directly as JSX props. Does NOT apply to:
- Code inside callbacks (`.then()`, event handlers)
- Code inside `useEffect`/`useMemo`/`useCallback` bodies
- Primitives (strings, numbers, booleans)
- Already memoized values (`useMemo`/`useCallback`)

Good:
- **Reasoning**: New object/function references break memoization of child components. Only matters when child IS memoized AND parent is NOT optimized by React Compiler.

```tsx
const reportData = useMemo(() => ({
reportID: report.reportID,
type: report.type,
isPinned: report.isPinned,
}), [report.reportID, report.type, report.isPinned]);
#### Before flagging: Run optimization check

**YOU MUST call `checkReactCompilerOptimization.ts` (available in PATH from `.claude/scripts/`) on EVERY .tsx file from the diff.**

return <ReportActionItem report={reportData} />
**Call the script ONCE per file, separately. DO NOT use loops or batch processing.**

Example usage:
```bash
checkReactCompilerOptimization.ts src/components/File1.tsx
checkReactCompilerOptimization.ts src/components/File2.tsx
```

Bad:
**NEVER use absolute or relative paths for this script. Call it by name only:**
- ✅ `checkReactCompilerOptimization.ts src/components/Example.tsx`
- ❌ `/home/runner/work/App/App/.claude/scripts/checkReactCompilerOptimization.ts ...`
- ❌ `./.claude/scripts/checkReactCompilerOptimization.ts ...`

**"File not found"** → Assume parent is optimized and skip PERF-4.
Comment thread
mateuuszzzzz marked this conversation as resolved.

#### Decision flow

1. **Parent in `parentOptimized`?** → YES = **Skip** (compiler auto-memoizes)

2. **Child has custom memo comparator that PREVENTS re-render for this prop?**
→ Use `sourcePath` from script output to read child's source file
→ Grep for `React.memo` or `memo(`
→ If custom comparator prevents re-render despite new reference for this prop → **Skip**

3. **Child is memoized?** (`optimized: true` OR `React.memo`)
Comment thread
mateuuszzzzz marked this conversation as resolved.
- NO → **Skip** (child re-renders anyway)
- YES → **Flag PERF-4**

#### Examples

**Flag** (parent NOT optimized, child IS memoized, no custom comparator):
```tsx
// Script output: parentOptimized: [], child MemoizedList optimized: true
// No custom comparator found
return <MemoizedList options={{ showHeader: true }} />;
```

**Skip - custom comparator** (comparator prevents re-render for this prop):
```tsx
const [report] = useOnyx(`ONYXKEYS.COLLECTION.REPORT${iouReport.id}`);
// Script output: sourcePath: "src/components/PopoverMenu.tsx"
// PopoverMenu.tsx has custom memo comparator that handles anchorPosition
return <PopoverMenu anchorPosition={{x: 0, y: 0}} />;
```

return <ReportActionItem report={report} />
**Skip - parent optimized**:
```tsx
// Script output: parentOptimized: ["MyComponent"]
// React Compiler auto-memoizes - no manual memoization needed
return <MemoizedList options={{ showHeader: true }} />;
```

**Skip - spread props with stable inner values**:
```tsx
// Spread is OK when inner values come from memoized sources
// illustration from useMemoizedLazyIllustrations, illustrationStyle from useThemeStyles
const illustration = useAboutSectionIllustration();
return <Section {...illustration} />;
```

---
Expand Down
2 changes: 1 addition & 1 deletion .claude/commands/review-code-pr.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
---
allowed-tools: Bash(gh pr comment:*),Bash(gh pr diff:*),Bash(gh pr view:*),Bash(addPrReaction.sh:*),Bash(createInlineComment.sh:*)
allowed-tools: Bash(gh pr comment:*),Bash(gh pr diff:*),Bash(gh pr view:*),Bash(addPrReaction.sh:*),Bash(createInlineComment.sh:*),Bash(checkReactCompilerOptimization.ts:*)
description: Review a code contribution pull request
---

Expand Down
Loading
Loading