# React Performance Optimization
Optimizing React performance is crucial for smooth user experiences. Here are key techniques and patterns:
import React, { memo, useMemo, useCallback, lazy, Suspense } from 'react';
// React.memo for preventing unnecessary re-rendersconst ExpensiveComponent = memo(function ExpensiveComponent({ data, onUpdate }) { console.log('ExpensiveComponent rendered');
return ( <div> {data.map(item => ( <div key={item.id} onClick={() => onUpdate(item.id)}> {item.name} </div> ))} </div> );});
// useMemo for expensive calculationsfunction DataProcessor({ items, filter }) { // Only recalculate when items or filter changes const processedData = useMemo(() => { console.log('Processing data...'); return items .filter(item => item.category === filter) .map(item => ({ ...item, processed: true, score: calculateComplexScore(item) })) .sort((a, b) => b.score - a.score); }, [items, filter]);
// useCallback to prevent function recreation const handleItemUpdate = useCallback((itemId) => { // Update logic here console.log('Updating item:', itemId); }, []); // Empty dependencies mean function never changes
return ( <div> <h2>Processed Items: {processedData.length}</h2> <ExpensiveComponent data={processedData} onUpdate={handleItemUpdate} /> </div> );}
function calculateComplexScore(item) { // Simulate expensive calculation let score = 0; for (let i = 0; i < 1000; i++) { score += item.value * Math.random(); } return score;}Code splitting and lazy loading:
import React, { lazy, Suspense } from 'react';import { BrowserRouter as Router, Routes, Route } from 'react-router-dom';
// Lazy load componentsconst Dashboard = lazy(() => import('./components/Dashboard'));const UserProfile = lazy(() => import('./components/UserProfile'));const Settings = lazy(() => import('./components/Settings'));
// Loading componentfunction LoadingSpinner() { return ( <div className="loading-container"> <div className="spinner">Loading...</div> </div> );}
function App() { return ( <Router> <div className="app"> <nav> {/* Navigation */} </nav>
<main> <Suspense fallback={<LoadingSpinner />}> <Routes> <Route path="/dashboard" element={<Dashboard />} /> <Route path="/profile" element={<UserProfile />} /> <Route path="/settings" element={<Settings />} /> </Routes> </Suspense> </main> </div> </Router> );}Virtualization for large lists:
import React, { useMemo } from 'react';import { FixedSizeList as List } from 'react-window';
function VirtualizedList({ items, height = 400, itemHeight = 50 }) { // Memoize item renderer const ItemRenderer = useMemo(() => { return ({ index, style }) => { const item = items[index]; return ( <div style={style} className="list-item"> <h4>{item.title}</h4> <p>{item.description}</p> <span>{item.category}</span> </div> ); }; }, [items]);
return ( <div className="virtualized-container"> <List height={height} itemCount={items.length} itemSize={itemHeight} itemData={items} > {ItemRenderer} </List> </div> );}
// Usage with thousands of itemsfunction LargeDataApp() { const [items] = useState(() => { // Generate large dataset return Array.from({ length: 10000 }, (_, index) => ({ id: index, title: `Item ${index}`, description: `Description for item ${index}`, category: `Category ${index % 5}` })); });
return ( <div> <h1>Large List ({items.length} items)</h1> <VirtualizedList items={items} /> </div> );}State management optimization:
import React, { useReducer, createContext, useContext, useMemo } from 'react';
// Context for state managementconst AppContext = createContext();
// Reducer for complex state logicfunction appReducer(state, action) { switch (action.type) { case 'ADD_ITEM': return { ...state, items: [...state.items, action.payload] }; case 'UPDATE_ITEM': return { ...state, items: state.items.map(item => item.id === action.payload.id ? { ...item, ...action.payload.updates } : item ) }; case 'SET_FILTER': return { ...state, filter: action.payload }; default: return state; }}
// Context provider with optimized valuefunction AppProvider({ children }) { const [state, dispatch] = useReducer(appReducer, { items: [], filter: 'all' });
// Memoize context value to prevent unnecessary re-renders const contextValue = useMemo(() => ({ state, dispatch }), [state]);
return ( <AppContext.Provider value={contextValue}> {children} </AppContext.Provider> );}
// Custom hook for using contextfunction useAppContext() { const context = useContext(AppContext); if (!context) { throw new Error('useAppContext must be used within AppProvider'); } return context;}# Install React Developer Tools browser extension# Use React Profiler to identify performance bottlenecks
# Bundle analysisnpm install --save-dev webpack-bundle-analyzernpm run buildnpx webpack-bundle-analyzer build/static/js/*.js
# Performance monitoringnpm install --save web-vitals