Install any skill in seconds. Free to start, no credit card required.
Get Started Free →Diagnose slow React components and suggest targeted performance fixes.
.claude/skills/davila7-react-component-performance/SKILL.md| Test case | Without → With | Effect | Δ tokens | Δ turns |
|---|---|---|---|---|
| case-17 | ✗→✓ | ▲ Improved | 2% | 0% |
| case-01 | ✓→✓ | = Same ✓ | 16% | 0% |
| case-02 | ✓→✓ | = Same ✓ | 19% | 0% |
| case-03 | ✓→✓ | = Same ✓ | 100% | 0% |
| case-04 | ✓→✓ | = Same ✓ | 48% | 0% |
Identify render hotspots, isolate expensive updates, and apply targeted optimizations without changing UI behavior.
memo only when props are stable.useCallback/useMemo for handlers and derived values.Move a timer or animation counter into a child so the parent list never re-renders on each tick.
tsx// ❌ Before – entire parent (and list) re-renders every second function Dashboard({ items }: { items: Item[] }) { const [tick, setTick] = useState(0); useEffect(() => { const id = setInterval(() => setTick(t => t + 1), 1000); return () => clearInterval(id); }, []); return ( <> <Clock tick={tick} /> <ExpensiveList items={items} /> {/* re-renders every second */} </> ); } // ✅ After – only <Clock> re-renders; list is untouched function Clock() { const [tick, setTick] = useState(0); useEffect(() => { const id = setInterval(() => setTick(t => t + 1), 1000); return () => clearInterval(id); }, []); return <span>{tick}s</span>; } function Dashboard({ items }: { items: Item[] }) { return ( <> <Clock /> <ExpensiveList items={items} /> </> ); }
useCallback + memotsx// ❌ Before – new handler reference on every render busts Row memo function List({ items }: { items: Item[] }) { const handleClick = (id: string) => console.log(id); // new ref each render return items.map(item => <Row key={item.id} item={item} onClick={handleClick} />); } // ✅ After – stable handler; Row only re-renders when its own item changes const Row = memo(({ item, onClick }: RowProps) => ( <li onClick={() => onClick(item.id)}>{item.name}</li> )); function List({ items }: { items: Item[] }) { const handleClick = useCallback((id: string) => console.log(id), []); return items.map(item => <Row key={item.id} item={item} onClick={handleClick} />); }
tsx// ❌ Before – recomputes on every render function Summary({ orders }: { orders: Order[] }) { const total = orders.reduce((sum, o) => sum + o.amount, 0); // runs every render return <p>Total: {total}</p>; } // ✅ After – recomputes only when orders changes function Summary({ orders }: { orders: Order[] }) { const total = useMemo(() => orders.reduce((sum, o) => sum + o.amount, 0), [orders]); return <p>Total: {total}</p>; }
Load references/examples.md when the user wants a concrete refactor example.
| Case | Status | Duration (ms) | Turns | Tokens | Tool calls | ||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Without | With | Δ | Without | With | Δ | Without | With | Δ | Without | With | Δ | ||
case-01 | pass→pass | 12,763 | 8,538 | -33% | 1 | 1 | 0% | 2,327 | 2,696 | +16% | 0 | 0 | — |
case-02 | pass→pass | 11,947 | 7,353 | -38% | 1 | 1 | 0% | 2,173 | 2,593 | +19% | 0 | 0 | — |
case-03 | pass→pass | 7,380 | 5,547 | -25% | 1 | 1 | 0% | 1,104 | 2,210 | +100% | 0 | 0 | — |
case-04 | pass→pass | 7,414 | 4,090 | -45% | 1 | 1 | 0% | 1,205 | 1,789 | +48% | 0 | 0 | — |
case-05 | pass→pass | 10,874 | 2,466 | -77% | 1 | 1 | 0% | 1,757 | 1,566 | -11% | 0 | 0 | — |
case-06 | pass→pass | 19,926 | 10,851 | -46% | 1 | 1 | 0% | 2,862 | 2,896 | +1% | 0 | 0 | — |
case-07 | pass→pass | 11,745 | 9,991 | -15% | 1 | 1 | 0% | 2,079 | 2,982 | +43% | 0 | 0 | — |
case-08 | pass→pass | 10,971 | 7,512 | -32% | 1 | 1 | 0% | 1,878 | 2,464 | +31% | 0 | 0 | — |
case-09 | pass→pass | 10,472 | 7,374 | -30% | 1 | 1 | 0% | 1,826 | 2,468 | +35% | 0 | 0 | — |
case-10 | pass→pass | 11,542 | 12,154 | +5% | 1 | 1 | 0% | 1,807 | 3,103 | +72% | 0 | 0 | — |
case-11 | pass→pass | 17,346 | 21,853 | +26% | 1 | 1 | 0% | 2,798 | 3,416 | +22% | 0 | 0 | — |
case-12 | pass→pass | 14,991 | 7,261 | -52% | 1 | 1 | 0% | 2,510 | 2,352 | -6% | 0 | 0 | — |
case-13 | pass→pass | 10,263 | 12,174 | +19% | 1 | 1 | 0% | 1,817 | 3,596 | +98% | 0 | 0 | — |
case-14 | pass→pass | 11,086 | 7,631 | -31% | 1 | 1 | 0% | 1,695 | 2,551 | +51% | 0 | 0 | — |
case-15 | pass→pass | 3,997 | 1,780 | -55% | 1 | 1 | 0% | 563 | 1,483 | +163% | 0 | 0 | — |
case-16 | pass→pass | 14,643 | 10,486 | -28% | 1 | 1 | 0% | 2,369 | 2,893 | +22% | 0 | 0 | — |
case-17 | fail→pass | 16,499 | 9,636 | -42% | 1 | 1 | 0% | 2,671 | 2,727 | +2% | 0 | 0 | — |
case-18 | pass→pass | 13,382 | 12,416 | -7% | 1 | 1 | 0% | 2,237 | 3,211 | +44% | 0 | 0 | — |
case-19 | fail→fail | 17,743 | 16,896 | -5% | 1 | 1 | 0% | 2,910 | 4,094 | +41% | 0 | 0 | — |
case-20 | fail→fail | 13,032 | 13,293 | +2% | 1 | 1 | 0% | 2,392 | 3,643 | +52% | 0 | 0 | — |
case-21 | fail→fail | 21,873 | 21,279 | -3% | 1 | 1 | 0% | 3,755 | 4,895 | +30% | 0 | 0 | — |
case-22 | fail→fail | 17,205 | 14,031 | -18% | 1 | 1 | 0% | 3,078 | 3,624 | +18% | 0 | 0 | — |
DecimalAI ran this skill against gemini-3.6-flash twice over the same eval suite — once with the skill loaded and once without — and compared the two runs case by case. 22 cases were attempted. The headline lift of +5 percentage points is the difference between those two pass rates over the 22 comparable cases.
Without the skill loaded, the model failed this case. With it loaded, the same prompt on the same model passed. This is one improved case from the latest verified run; every case, including any that regressed, is in the table above.
Other measured skills in the registry, with their headline benchmark lift.