Ways to optimize performance in Functional React applications

Ways to optimize performance in Functional React applications

ยท

3 min read

When there is a very large react project then any optimization that can minimize the number of re-renders of the UI can improve the performance of the application.

1) Memoization

Memoization means storing computation results in a cache and retrieving that same information from the cache the next time it's needed instead of computing it again.

This allows to isolate resource-intensive functions so that they will not automatically run on every render.

Memoization in react can be applied using useCallback() or useMemo() hook or React.memo()

useCallback() :

useCallback returns a memoized function and it will make the function which it is wrapping, run only when the dependencies change.

const memoized = useCallback(() => {
   // the callback function to be memoized
 },
  // dependencies array
[]);

useMemo() :

useMemo Hook returns a memoized value and prevents the application from unnecessary re-renders. It is useful in heavy computations and processes when using functional components.

const memoizedValue = useMemo(functionThatReturnsValue, 
arrayOfDependencies)

React.memo() :

React.memo() is a Higher Order Function, or HOC which will cause React to skip rendering a component if its props have not changed. This can improve performance.

const Example = (props) => {
  console.log("Rendering");
  return <div>{props.title}</div>;
};
export default React.memo(Example);

2) Code Splitting

Code splitting means splitting the code into smaller chunks and in that case, the whole codebase is not loaded at once, instead only the code required for the current page or the component is loaded which improves the initial loading time of your application.

Code splitting in react can be achieved using tools/bundlers like webpack, rollup, or parcel.

3) Lazy loading

In lazy loading, the loading of a component is delayed until they are needed. Lazy loading can be applied using React.lazy() and Suspense() component. For example, you can initially load the components and modules related to user login and registration. Then, you can load the rest of the components based on user navigation.

React.lazy()

React.lazy() allows developers to easily create components with dynamic imports and render them as normal components. When the component is rendered, it will automatically load the bundle that contains the rendered component.

// Without React.lazy()
import AboutComponent from './AboutComponent ';

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

const HomeComponent = () => (
    <div><AboutComponent /></div>
)

React.Suspense

When we use lazy loading, components are rendered as we navigate. So, we need to have a placeholder for those components until they are loaded. As a solution, React.Suspense was introduced, and it acts as a wrapper for the lazy components. It accepts a prop named fallback as the placeholder, and you can pass a component or an element for that.

import React, { Suspense } from "react";
const AboutComponent = React.lazy(() => import('./AboutComponent'));

const HomeComponent = () => (
    <div><Suspense fallback = { <div> Please Wait... </div> } >
            <AboutComponent /></Suspense></div>
);

Optimizing Images

Images are one of the primary culprits for slow loading websites. You can optimize images by compressing them without compromising their quality. Tools like tinyPng can compress your images and help you reduce the size of your website, and therefore it's load time. Meta frameworks such as Next come with built-in image optimization.

As always, I hope you enjoyed the article and learned something new.

If you want, you can also follow me on LinkedIn or Twitter. See you in the next one!

ย