React's declarative nature makes it easy to write code, but this simplicity often hides performance pitfalls. After auditing dozens of production React apps, I've identified these recurring issues.
Every render recalculates values in your component body. For complex operations, this wastes CPU cycles and can cause noticeable lag.
// ❌ Recalculates on every render
const sortedList = hugeArray.sort(complexSort);
return <List items={sortedList} />;
New function references on each render break memoization and cause child components to re-render unnecessarily.
Problem
<Child onClick={() => handleClick(id)} />
Creates new function on every renderSolution
const handleChildClick = useCallback(
() => handleClick(id),
[id]
);
<Child onClick={handleChildClick} />
Stable function referenceUsing useState for data that never changes triggers unnecessary re-renders and consumes memory.
Common culprits: Configuration objects, constant lists, environment variables
// ❌ Unnecessary state
const [config] = useState({ apiUrl: '...', theme: 'dark' });
// ✅ Better alternatives:
const config = { apiUrl: '...', theme: 'dark' }; // Plain object
const config = useRef({ apiUrl: '...', theme: 'dark' }).current; // Ref
const config = useMemo(() => ({ apiUrl: '...', theme: 'dark' }), []);
Rendering hundreds/thousands of list items DOM nodes cripples performance.
Solution: Use windowing libraries like react-window or react-virtualized
import { FixedSizeList as List } from 'react-window';
const Row = ({ index, style }) => (
<div style={style}>Row {index}</div>
);
const MyList = () => (
<List
height={500}
itemCount={1000}
itemSize={35}
width={300}
>
{Row}
</List>
);
Large JavaScript bundles delay interactive time, especially on mobile.
Splits your app into smaller chunks
Identifies heavy dependencies
Like lodash-es instead of lodash
Example of code splitting routes:
// Before
import HeavyComponent from './HeavyComponent';
// After
const HeavyComponent = React.lazy(() => import('./HeavyComponent'));
// Usage with Suspense
<Suspense fallback={<Spinner />}>
<HeavyComponent />
</Suspense>
Use these tools to identify performance issues:
React DevTools
Component profiling
Chrome Lighthouse
Performance metrics
Why Did You Render
Re-render tracking
Webpack Bundle Analyzer
Bundle size visualization