DEV Community

Cover image for Optimizing React Applications: Simple Techniques for Better Performance
Zachée Niyokwizera
Zachée Niyokwizera

Posted on

Optimizing React Applications: Simple Techniques for Better Performance

React is a popular tool for building user interfaces, but as apps get bigger, they can slow down. In this article, I will be going through different techniques that you can use to optimize your React app.

1. Avoid Unnecessary Re-renders with React.memo

If you have a component that doesn’t need to update all the time, wrap it with React.memo. This helps React remember the last output and skip re-rendering if nothing has changed.

import React from 'react';

const MyComponent = React.memo((props) => {
  // Your component logic
});
Enter fullscreen mode Exit fullscreen mode

2. Prevent Extra Work with PureComponent

If you're using class components, extend React.PureComponent instead of React.Component. This tells React to only re-render if the props or state actually change.

import React from 'react';

class MyComponent extends React.PureComponent {
  // Your component logic
}
Enter fullscreen mode Exit fullscreen mode

3. Use useCallback and useMemo to Save Work

React hooks useCallback and useMemo help you save work by remembering functions and values. This avoids creating new ones every time the component renders.

  • useCallback: Remembers a function.
const memoizedCallback = useCallback(() => {
  doSomething(a, b);
}, [a, b]);
Enter fullscreen mode Exit fullscreen mode
  • useMemo: Remembers a value.
const memoizedValue = useMemo(() => computeExpensiveValue(a, b), [a, b]);
Enter fullscreen mode Exit fullscreen mode

4. Load Code on Demand with React.lazy and Suspense

Load parts of your code only when needed using React.lazy and Suspense. This makes your initial load faster.

import React, { Suspense } from 'react';

const LazyComponent = React.lazy(() => import('./LazyComponent'));

function MyComponent() {
  return (
    <Suspense fallback={<div>Loading...</div>}>
      <LazyComponent />
    </Suspense>
  );
}
Enter fullscreen mode Exit fullscreen mode

5. Split Code by Routes

Load only the code you need for each page by splitting your code by routes. This speeds up initial load times.

import { BrowserRouter as Router, Route, Switch } from 'react-router-dom';
import React, { lazy, Suspense } from 'react';

const Home = lazy(() => import('./Home'));
const About = lazy(() => import('./About'));

function App() {
  return (
    <Router>
      <Suspense fallback={<div>Loading...</div>}>
        <Switch>
          <Route path="/" exact component={Home} />
          <Route path="/about" component={About} />
        </Switch>
      </Suspense>
    </Router>
  );
}
Enter fullscreen mode Exit fullscreen mode

6. Lazy Load Images and Components

Delay loading images and components until they are needed. This improves initial load time and performance.

  • Lazy Load Images: Use the loading attribute in the img tag to defer offscreen images.
<img src="image.jpg" alt="Description" loading="lazy" />
Enter fullscreen mode Exit fullscreen mode
  • Lazy Load Components: Use React.lazy and Suspense for components.
import React, { Suspense } from 'react';

const LazyComponent = React.lazy(() => import('./LazyComponent'));

function MyComponent() {
  return (
    <Suspense fallback={<div>Loading...</div>}>
      <LazyComponent />
    </Suspense>
  );
}
Enter fullscreen mode Exit fullscreen mode

7. Avoid Inline Functions in JSX

Inline functions in JSX can slow things down because they create new instances every time. Define them outside the render method or use useCallback.

// Instead of this
<button onClick={() => doSomething()}>Click me</button>

// Do this
const handleClick = useCallback(() => {
  doSomething();
}, []);
<button onClick={handleClick}>Click me</button>
Enter fullscreen mode Exit fullscreen mode

8. Optimize Large Lists with React Virtualization

When dealing with large lists, use libraries like react-window or react-virtualized to only render what’s visible on the screen, reducing the load.

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

const MyList = ({ items }) => (
  <List
    height={500}
    itemCount={items.length}
    itemSize={35}
    width={300}
  >
    {({ index, style }) => (
      <div style={style}>
        {items[index]}
      </div>
    )}
  </List>
);
Enter fullscreen mode Exit fullscreen mode

9. Throttle and Debounce Events

Throttle or debounce frequent functions to control how often they run. This is especially useful for events like scrolling or typing.

import { useCallback } from 'react';
import { debounce } from 'lodash';

const handleInputChange = useCallback(
  debounce((value) => {
    // Handle the change
  }, 300),
  []
);
Enter fullscreen mode Exit fullscreen mode

10. Use Unique Keys for Lists

Make sure each list item has a unique key prop. This helps React track items and update them efficiently.

const items = list.map((item) => (
  <ListItem key={item.id} {...item} />
));
Enter fullscreen mode Exit fullscreen mode

11. Deploy the Production Build

Always use the production build for your React app to benefit from optimizations like minification and dead code elimination.

# Create a production build
npm run build
Enter fullscreen mode Exit fullscreen mode

By using these techniques, you can make your React applications faster and more efficient, providing a better experience for your users. Optimization is an ongoing process, so keep profiling and improving your app regularly.

Happy coding.

Top comments (0)