# 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-renders
const 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 calculations
function 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 components
const Dashboard = lazy(() => import('./components/Dashboard'));
const UserProfile = lazy(() => import('./components/UserProfile'));
const Settings = lazy(() => import('./components/Settings'));
// Loading component
function 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 items
function 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 management
const AppContext = createContext();
// Reducer for complex state logic
function 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 value
function 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 context
function useAppContext() {
const context = useContext(AppContext);
if (!context) {
throw new Error('useAppContext must be used within AppProvider');
}
return context;
}
React Performance Analysis
# Install React Developer Tools browser extension
# Use React Profiler to identify performance bottlenecks
# Bundle analysis
npm install --save-dev webpack-bundle-analyzer
npm run build
npx webpack-bundle-analyzer build/static/js/*.js
# Performance monitoring
npm install --save web-vitals
My avatar

Thanks for reading my blog post! Feel free to check out my other posts or contact me via the social links in the footer.


More Posts

Comments