KS
Killer-Skills

react-performance — how to use react-performance how to use react-performance, react-performance optimization techniques, react-performance vs react-optimization, react-performance setup guide, what is react-performance, react-performance install, react-performance alternative, react-performance best practices, react-performance tutorial, react-performance examples

v1.0.0
GitHub

About this Skill

Perfect for Frontend Agents needing optimized React application performance. React-performance is a set of techniques and patterns for improving the rendering speed and efficiency of React applications, including memoization and optimization of lists and computations.

Features

Utilizes useMemo for memoizing expensive calculations
Optimizes lists through filtering and sorting
Minimizes unnecessary re-renders for faster rendering
Improves application performance through efficient computation handling
Applies memoization patterns for optimized rendering behavior
Supports optimized rendering for complex React components

# Core Topics

CJHarmath CJHarmath
[0]
[0]
Updated: 3/6/2026

Quality Score

Top 5%
39
Excellent
Based on code quality & docs
Installation
SYS Universal Install (Auto-Detect)
Cursor IDE Windsurf IDE VS Code IDE
> npx killer-skills add CJHarmath/claude-agents-skills/react-performance

Agent Capability Analysis

The react-performance MCP Server by CJHarmath is an open-source Categories.community integration for Claude and other AI agents, enabling seamless task automation and capability expansion. Optimized for how to use react-performance, react-performance optimization techniques, react-performance vs react-optimization.

Ideal Agent Persona

Perfect for Frontend Agents needing optimized React application performance.

Core Value

Empowers agents to minimize unnecessary re-renders and computations, leveraging techniques like memoization with useMemo, to build high-performance web applications using React.

Capabilities Granted for react-performance MCP Server

Optimizing React component re-renders
Improving list rendering performance
Reducing expensive computations on the main thread

! Prerequisites & Limits

  • Requires understanding of React's rendering behavior
  • Limited to React applications only
Project
SKILL.md
9.9 KB
.cursorrules
1.2 KB
package.json
240 B
Ready
UTF-8

# Tags

[No tags]
SKILL.md
Readonly

React Performance (Web)

Problem Statement

React performance issues often stem from unnecessary re-renders, unoptimized lists, and expensive computations on the main thread. Understanding React's rendering behavior is key to building performant applications.


Pattern: Memoization

useMemo - Expensive Computations

typescript
1// ✅ CORRECT: Memoize expensive calculation 2const sortedAndFilteredItems = useMemo(() => { 3 return items 4 .filter(item => item.active) 5 .sort((a, b) => b.score - a.score) 6 .slice(0, 100); 7}, [items]); 8 9// ❌ WRONG: Recalculates every render 10const sortedAndFilteredItems = items 11 .filter(item => item.active) 12 .sort((a, b) => b.score - a.score); 13 14// ❌ WRONG: Memoizing simple access (overhead > benefit) 15const userName = useMemo(() => user.name, [user.name]);

When to use useMemo:

  • Array transformations (filter, sort, map chains)
  • Object creation passed to memoized children
  • Computations with O(n) or higher complexity

useCallback - Stable Function References

typescript
1// ✅ CORRECT: Stable callback for child props 2const handleClick = useCallback((id: string) => { 3 setSelectedId(id); 4}, []); 5 6// Pass to memoized child 7<MemoizedItem onClick={handleClick} /> 8 9// ❌ WRONG: useCallback with unstable deps 10const handleClick = useCallback((id: string) => { 11 doSomething(unstableObject); // unstableObject changes every render 12}, [unstableObject]); // Defeats the purpose

When to use useCallback:

  • Callbacks passed to memoized children
  • Callbacks in dependency arrays
  • Event handlers that would cause child re-renders

Pattern: React.memo

typescript
1// Wrap components that receive stable props 2const ItemCard = memo(function ItemCard({ 3 item, 4 onSelect 5}: Props) { 6 return ( 7 <div onClick={() => onSelect(item.id)}> 8 <h3>{item.name}</h3> 9 <p>{item.price}</p> 10 </div> 11 ); 12}); 13 14// Custom comparison for complex props 15const ItemCard = memo( 16 function ItemCard({ item, onSelect }: Props) { 17 // ... 18 }, 19 (prevProps, nextProps) => { 20 // Return true if props are equal (skip re-render) 21 return ( 22 prevProps.item.id === nextProps.item.id && 23 prevProps.item.price === nextProps.item.price 24 ); 25 } 26);

When to use React.memo:

  • List item components
  • Components receiving stable primitive props
  • Components that render frequently but rarely change

When NOT to use:

  • Components that always receive new props
  • Simple components (overhead > benefit)
  • Root-level pages

Pattern: List Virtualization

For long lists, render only visible items using react-window or react-virtualized.

typescript
1import { FixedSizeList } from 'react-window'; 2 3function VirtualizedList({ items }: { items: Item[] }) { 4 const Row = ({ index, style }: { index: number; style: React.CSSProperties }) => ( 5 <div style={style}> 6 <ItemCard item={items[index]} /> 7 </div> 8 ); 9 10 return ( 11 <FixedSizeList 12 height={600} 13 width="100%" 14 itemCount={items.length} 15 itemSize={80} 16 > 17 {Row} 18 </FixedSizeList> 19 ); 20} 21 22// Variable height items 23import { VariableSizeList } from 'react-window'; 24 25function VariableList({ items }: { items: Item[] }) { 26 const getItemSize = (index: number) => { 27 return items[index].expanded ? 200 : 80; 28 }; 29 30 return ( 31 <VariableSizeList 32 height={600} 33 width="100%" 34 itemCount={items.length} 35 itemSize={getItemSize} 36 > 37 {Row} 38 </VariableSizeList> 39 ); 40}

When to virtualize:

  • Lists with 100+ items
  • Complex item components
  • Scrollable containers with many children

Pattern: Zustand Selector Optimization

Problem: Selecting entire store causes re-render on any state change.

typescript
1// ❌ WRONG: Re-renders on ANY store change 2const store = useAppStore(); 3// or 4const { items, loading, filters, ... } = useAppStore(); 5 6// ✅ CORRECT: Only re-renders when selected values change 7const items = useAppStore((s) => s.items); 8const loading = useAppStore((s) => s.loading); 9 10// ✅ CORRECT: Multiple values with shallow comparison 11import { useShallow } from 'zustand/react/shallow'; 12 13const { items, loading } = useAppStore( 14 useShallow((s) => ({ 15 items: s.items, 16 loading: s.loading 17 })) 18);

Pattern: Avoiding Re-Renders

Object/Array Stability

typescript
1// ❌ WRONG: New object every render 2<ChildComponent style={{ padding: 10 }} /> 3<ChildComponent config={{ enabled: true }} /> 4 5// ✅ CORRECT: Stable reference 6const style = useMemo(() => ({ padding: 10 }), []); 7const config = useMemo(() => ({ enabled: true }), []); 8 9<ChildComponent style={style} /> 10<ChildComponent config={config} /> 11 12// ✅ CORRECT: Or define outside component 13const style = { padding: 10 }; 14 15function Parent() { 16 return <ChildComponent style={style} />; 17}

Children Stability

typescript
1// ❌ WRONG: Inline function creates new element each render 2<Parent> 3 {() => <Child />} 4</Parent> 5 6// ✅ CORRECT: Stable element 7const child = useMemo(() => <Child />, [deps]); 8<Parent>{child}</Parent>

Pattern: Code Splitting

typescript
1import { lazy, Suspense } from 'react'; 2 3// Lazy load components 4const Dashboard = lazy(() => import('./pages/Dashboard')); 5const Settings = lazy(() => import('./pages/Settings')); 6 7function App() { 8 return ( 9 <Suspense fallback={<Loading />}> 10 <Routes> 11 <Route path="/dashboard" element={<Dashboard />} /> 12 <Route path="/settings" element={<Settings />} /> 13 </Routes> 14 </Suspense> 15 ); 16} 17 18// Named exports 19const Dashboard = lazy(() => 20 import('./pages/Dashboard').then(module => ({ 21 default: module.Dashboard 22 })) 23);

Pattern: Debouncing and Throttling

typescript
1import { useMemo } from 'react'; 2import { debounce, throttle } from 'lodash-es'; 3 4// Debounce - wait until user stops typing 5function SearchInput({ onSearch }: { onSearch: (query: string) => void }) { 6 const debouncedSearch = useMemo( 7 () => debounce(onSearch, 300), 8 [onSearch] 9 ); 10 11 return ( 12 <input 13 type="text" 14 onChange={(e) => debouncedSearch(e.target.value)} 15 /> 16 ); 17} 18 19// Throttle - limit how often function runs 20function InfiniteScroll({ onLoadMore }: { onLoadMore: () => void }) { 21 const throttledLoad = useMemo( 22 () => throttle(onLoadMore, 1000), 23 [onLoadMore] 24 ); 25 26 useEffect(() => { 27 const handleScroll = () => { 28 if (nearBottom()) { 29 throttledLoad(); 30 } 31 }; 32 33 window.addEventListener('scroll', handleScroll); 34 return () => window.removeEventListener('scroll', handleScroll); 35 }, [throttledLoad]); 36 37 return <div>...</div>; 38}

Pattern: Image Optimization

typescript
1// Lazy load images 2<img 3 src={imageUrl} 4 loading="lazy" 5 alt="Description" 6/> 7 8// With intersection observer for more control 9function LazyImage({ src, alt }: { src: string; alt: string }) { 10 const [isVisible, setIsVisible] = useState(false); 11 const imgRef = useRef<HTMLDivElement>(null); 12 13 useEffect(() => { 14 const observer = new IntersectionObserver( 15 ([entry]) => { 16 if (entry.isIntersecting) { 17 setIsVisible(true); 18 observer.disconnect(); 19 } 20 }, 21 { rootMargin: '100px' } 22 ); 23 24 if (imgRef.current) { 25 observer.observe(imgRef.current); 26 } 27 28 return () => observer.disconnect(); 29 }, []); 30 31 return ( 32 <div ref={imgRef}> 33 {isVisible ? ( 34 <img src={src} alt={alt} /> 35 ) : ( 36 <div className="placeholder" /> 37 )} 38 </div> 39 ); 40} 41 42// Next.js Image component (if using Next.js) 43import Image from 'next/image'; 44 45<Image 46 src={imageUrl} 47 alt="Description" 48 width={400} 49 height={300} 50 placeholder="blur" 51 blurDataURL={blurHash} 52/>

Pattern: Web Workers for Heavy Computation

typescript
1// worker.ts 2self.onmessage = (e: MessageEvent<{ data: number[] }>) => { 3 const result = heavyComputation(e.data.data); 4 self.postMessage(result); 5}; 6 7// Component 8function DataProcessor({ data }: { data: number[] }) { 9 const [result, setResult] = useState(null); 10 11 useEffect(() => { 12 const worker = new Worker(new URL('./worker.ts', import.meta.url)); 13 14 worker.onmessage = (e) => { 15 setResult(e.data); 16 }; 17 18 worker.postMessage({ data }); 19 20 return () => worker.terminate(); 21 }, [data]); 22 23 return result ? <Results data={result} /> : <Loading />; 24}

Pattern: Detecting Re-Renders

React DevTools Profiler

  1. Open React DevTools
  2. Go to Profiler tab
  3. Click record, interact, stop
  4. Review "Flamegraph" for render times
  5. Look for components rendering unnecessarily

why-did-you-render

typescript
1// Setup in development 2import React from 'react'; 3 4if (process.env.NODE_ENV === 'development') { 5 const whyDidYouRender = require('@welldone-software/why-did-you-render'); 6 whyDidYouRender(React, { 7 trackAllPureComponents: true, 8 }); 9} 10 11// Mark specific component for tracking 12ItemCard.whyDidYouRender = true;

Console Logging

typescript
1// Quick check for re-renders 2function ItemCard({ item }: Props) { 3 console.log('ItemCard render:', item.id); 4 // ... 5}

Performance Checklist

Before shipping:

  • Large lists are virtualized
  • List items are memoized with React.memo
  • Callbacks passed to items use useCallback
  • Zustand selectors are specific (not whole store)
  • Images use lazy loading
  • Heavy routes are code-split
  • No inline object/function props to memoized children
  • Profiler shows no unnecessary re-renders

Common Issues

IssueSolution
List scroll lagVirtualize list, memoize items
Component re-renders too oftenCheck selector specificity, memoize props
Slow initial renderCode split, reduce bundle size
Memory growingCheck for event listener cleanup, state accumulation
UI freezes on interactionMove computation to web worker or defer

Relationship to Other Skills

  • react-zustand-patterns: Selector optimization patterns
  • react-async-patterns: Proper async handling prevents re-render loops

Related Skills

Looking for an alternative to react-performance or building a Categories.community AI Agent? Explore these related open-source MCP Servers.

View All

widget-generator

Logo of f
f

widget-generator is an open-source AI agent skill for creating widget plugins that are injected into prompt feeds on prompts.chat. It supports two rendering modes: standard prompt widgets using default PromptCard styling and custom render widgets built as full React components.

149.6k
0
Design

chat-sdk

Logo of lobehub
lobehub

chat-sdk is a unified TypeScript SDK for building chat bots across multiple platforms, providing a single interface for deploying bot logic.

73.0k
0
Communication

zustand

Logo of lobehub
lobehub

The ultimate space for work and life — to find, build, and collaborate with agent teammates that grow with you. We are taking agent harness to the next level — enabling multi-agent collaboration, effortless agent team design, and introducing agents as the unit of work interaction.

72.8k
0
Communication

data-fetching

Logo of lobehub
lobehub

The ultimate space for work and life — to find, build, and collaborate with agent teammates that grow with you. We are taking agent harness to the next level — enabling multi-agent collaboration, effortless agent team design, and introducing agents as the unit of work interaction.

72.8k
0
Communication