Optimizing React Applications: Simple Techniques for Better Performance
Zachée Niyokwizera
Posted on August 6, 2024
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
});
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
}
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]);
-
useMemo
: Remembers a value.
const memoizedValue = useMemo(() => computeExpensiveValue(a, b), [a, b]);
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>
);
}
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>
);
}
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 theimg
tag to defer offscreen images.
<img src="image.jpg" alt="Description" loading="lazy" />
-
Lazy Load Components:
Use
React.lazy
andSuspense
for components.
import React, { Suspense } from 'react';
const LazyComponent = React.lazy(() => import('./LazyComponent'));
function MyComponent() {
return (
<Suspense fallback={<div>Loading...</div>}>
<LazyComponent />
</Suspense>
);
}
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>
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>
);
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),
[]
);
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} />
));
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
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.
Posted on August 6, 2024
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.