πŸš€Stop Re-Rendering! 7 Practical Ways to Optimize React Performance



This content originally appeared on DEV Community and was authored by Rayan Hossain

Introduction

Performance is one of the most crucial aspects of building modern web applications. In React, a common bottleneck is unnecessary re-renders, which can slow down apps, increase memory usage, and hurt user experience.

The good news? With a few smart techniques, you can significantly optimize React performance and make your applications run smoothly.

In this article, we’ll go over 7 practical tips to stop unnecessary re-rendering in React.

Why Performance Matters in React

  • Faster load times improve user experience
  • Optimized apps reduce memory usage
  • Better performance means higher SEO rankings
  • Smooth interactions = happier users

Unnecessary re-renders are one of the most common culprits behind poor performance. Let’s fix that.

1⃣ Use React.memo for Pure Functional Components

If your component always renders the same output given the same props, you can wrap it with React.memo.

import React from "react";

const Button = ({ onClick, label }) => {
  console.log("Rendered:", label);
  return <button onClick={onClick}>{label}</button>;
};

export default React.memo(Button);

βœ… Great for pure functional components that receive the same props frequently.
⚠ Avoid overusing it, as unnecessary memoization can add overhead.

2⃣ Optimize Props with useCallback & useMemo

Functions and objects in JavaScript are reference types. Passing new references as props causes re-renders.

  • useCallback β†’ Memoize functions
  • useMemo β†’ Memoize values
import React, { useState, useCallback, useMemo } from "react";

function App() {
  const [count, setCount] = useState(0);

  const handleClick = useCallback(() => {
    setCount(c => c + 1);
  }, []);

  const expensiveValue = useMemo(() => {
    return count * 2;
  }, [count]);

  return (
    <div>
      <button onClick={handleClick}>Increase</button>
      <p>Expensive Value: {expensiveValue}</p>
    </div>
  );
}

βœ… Use useCallback for event handlers
βœ… Use useMemo for expensive calculations
βœ… Prevents unnecessary re-renders in children.
βœ… Great for performance-heavy calculations.

3⃣ Split Code with React.lazy & Suspense

Large bundles increase initial load time. Code-splitting with React.lazy helps load components only when needed.

import React, { Suspense, lazy } from "react";

const Dashboard = lazy(() => import("./Dashboard"));

function App() {
  return (
    <Suspense fallback={<p>Loading...</p>}>
      <Dashboard />
    </Suspense>
  );
}

βœ… Improves initial page load speed
βœ… Users only download what they need
βœ… Improves Core Web Vitals for SEO.

4⃣ Virtualize Long Lists with react-window / react-virtualized

Rendering thousands of DOM elements at once is costly. Use list virtualization to render only what’s visible.

import { FixedSizeList as List } from "react-window";

const Row = ({ index, style }) => (
  <div style={style}>Row {index}</div>
);

function App() {
  return (
    <List height={400} itemCount={1000} itemSize={35} width={300}>
      {Row}
    </List>
  );
}

βœ… Efficiently handles large datasets
βœ… Reduces memory usage and re-renders

5⃣ Avoid Anonymous Functions in JSX

Defining functions inside JSX causes a new function instance on every render, which may trigger re-renders.

❌ Bad Practice:

<button onClick={() => setCount(count + 1)}>Click</button>

βœ… Good:

const handleClick = () => setCount(count + 1);

<button onClick={handleClick}>Click</button>

βœ… Avoids new references on each render.
βœ… Works great with React.memo.

6⃣ Key Usage Best Practices in Lists

Incorrect key props can cause React to re-render unnecessarily.

βœ… Always use unique and stable keys:

{users.map(user => (
  <UserCard key={user.id} user={user} />
))}

❌ Avoid using array indexes as keys (except for static lists).

7⃣ Performance Profiling with React DevTools

Before optimizing blindly, use the React DevTools Profiler to measure performance.

Steps:

Install React DevTools extension

Switch to the Profiler tab

Record interactions to see which components re-render unnecessarily

βœ… Helps you focus only on real bottlenecks

🎯 Conclusion

Optimizing React performance doesn’t mean prematurely adding complexity. Instead, focus on preventing unnecessary re-renders and loading only what’s required.

βœ… Quick Recap of 7 Tips:

Use React.memo

Optimize with useCallback & useMemo

Split code with React.lazy & Suspense

Virtualize long lists

Avoid anonymous functions in JSX

Use proper keys in lists

Profile with React DevTools

πŸ‘‰ Remember: Always profile before optimizingβ€”don’t fix what isn’t broken.

With these techniques, your React apps will feel faster, smoother, and more professional. πŸš€


This content originally appeared on DEV Community and was authored by Rayan Hossain