DEV Community

Ishan Bagchi
Ishan Bagchi

Posted on

Ways to optimize React App

React is a well-liked library for JavaScript user interface development. Declarative syntax, component-based architecture, and quick rendering are just a few of its numerous advantages. But, when your React project expands in size and complexity, you might run into some performance problems that compromise the user experience. Fortunately, there are certain methods and resources that can assist you in improving the speed and fluidity of your React project. We'll look at a few of these methods in this article and show you how to use them in your React app.

Use functional components

Using functional components rather than class-based ones is one of the easiest ways to improve your React application. Writing, testing, and using functional components are easier. They don't need to construct instances or bind methods, therefore they have less overhead than class-based components. React hooks, a potent technique to manage state and side effects without utilising classes or lifecycle methods, may also be used by functional components.

Memoize React components

Memorizing your components is another technique to improve your React application.  Memoization is a technique that entails caching a function call's output and returning it when the same input is supplied once more. Performance can be enhanced and pointless recomputation can be avoided. React has two built-in methods for memoizing components: React.memo() and useMemo().

A higher-order component called React.memo() wraps around a functional component to stop it from re-rendering if its props are only marginally the same as the previous props. This is advantageous for pure components that have no internal states or side effects and just rely on their props.

A custom hook called useMemo() uses a dependency array to return a memoized item. It can be used to memoize complex calculations or procedures that produce JSX elements. By doing this, the calculations or routines won't need to be repeated after each render.

Code-splitting

By lowering the initial bundle size and loading time of your app, code-splitting is another method that can enhance the efficiency of your React project. Code splitting is the process of dividing your code into smaller pieces that can be loaded concurrently or on demand. By doing this, you only load the code required for the current page or feature and save the rest for when it is actually needed.

Using dynamic import() is one of the simplest ways to create code-splitting in your React application. Instead of using static statements, dynamic import() enables you to import modules as functions. When the module is loaded, this yields a promise that resolves with the module object.

React.lazy(), a built-in function that enables you to render a lazy component that will load asynchronously when it is rendered for the first time, can be used with dynamic import().

Windowing

Another method for improving the efficiency of your React project while rendering lengthy lists or data grids is windowing. Windowing is the process of only rendering a portion of the items that are now visible on the screen and recycling them when the user scrolls across the list or grid. By avoiding the creation of pointless DOM nodes, you can save memory and speed up rendering.

Using react-window, a module that offers various components for effectively presenting huge lists and grids with windowing, is one of the simplest ways to add windowing in your React project.

Lazy loading images

By minimising network requests and bandwidth usage when loading photos on your website, lazy loading images is another method that can improve the efficiency of your React project. Instead of loading all of the photos at once when the page loads, lazy loading entails just loading images when they are close to or within the viewport (the part of the web page that is visible to the user).

Using react-lazyload, a library that offers numerous components for slowly loading photos (or any other elements) with various settings like placeholders, thresholds, debounce intervals, etc., is one of the simplest ways to integrate lazy loading images in your React app.

Use immutable data structures

Data structures that are immutable cannot be changed once they have been formed. They provide a number of advantages for performance improvement, including:

  • Easier change detection: To compare immutable data structures, use strict equality checks (===) rather than deep equality checks (isEqual).
  • Faster copying: Shallow copying can be used to construct new immutable data structures from older ones instead of deep cloning.
  • Better concurrency: When implementing immutable data structures, you can prevent race situations and modifications caused by distinct threads or processes.

Although React does not by default enforce immutability, you can create and work with immutable data structures in your app by using libraries like immutable.js or immer.js.

In conclusion, improving a React app can significantly enhance both its usability and performance. To find areas for improvement, it's critical to periodically track and evaluate your app's performance. You can make sure that your React application functions quickly and effectively by putting these optimisation strategies into practise.

Top comments (2)

Collapse
 
brense profile image
Rense Bakker

Great suggestions! I have one comment about React.memo though. I would advice to not prematurely memoize components using React.memo. it adds overhead to your components, which doesn't do anything in most cases. I would advice to mostly use it only when you have a very specific use case that you need to write special update logic for, using the 2nd argument of React.memo to add your custom update logic:
react.dev/reference/react/memo#spe... Or when you are really sure that it will massively help performance to skip rendering, for example when the memoized component is high up in the tree, where skipping renders actually has an effect. Memoizing child components has very little to no effect on your app's performance and could obscure an actual problem with the internals of the child, like a useEffect that's triggering from a non-memoized callback for example.

Collapse
 
ishanbagchi profile image
Ishan Bagchi

Thanks for the comment. Will definitely keep it in mind. :-)