Some best techniques to Optimize your React App🐱‍💻
Published: 2022-09-12 18:51:50

---
title: Some best techniques to Optimize your React App🐱‍💻
published: true
date: 2022-08-31 11:17:12 UTC
tags: 
canonical_url: https://blog.sagarmedtiya.me/some-best-techniques-to-optimize-your-react-app
---
![image](https://cdn.hashnode.com/res/hashnode/image/upload/v1661751226264/hhHEVM6R2.gif)
Improving the web🌐 application performance plays an important role to improve User Experience and keep users engaged. However, it can be challenging to optimize your React App for performance. This post will cover some techniques to improve your React code.

Lets see what all important best optimization techniques we can apply to the React code.

## 🍀shouldComponentUpdate

The `shouldComponentUpdate` is a lifecycle method in react. This method makes the react component to re-render whenever there are changes in state or props and that change will affect the output.

For more detailed blog, you can have a look to this [blog](https://blog.sagarmedtiya.me/component-lifecycle-in-reactjs#heading-shouldcomponentupdate).

It helps in checking whether re-rendering is required or not. If re-rendering is not required then shouldComponentUpdate does not render the code. For example, if you want certain code to not re-render then this method can be of very handy.

**Note:** It is encouraged to use functional components over class components. With functional component you can use `useMemo()` and `React.memo` hooks.

```
function shouldComponentUpdate(nextProps, nextState){
    return nextProps.id !== this.props.id;
}

```

## 🍀Lazy Loading

![Lazy Loading.gif](https://cdn.hashnode.com/res/hashnode/image/upload/v1661931273580/HEUf-aSWy.gif)Lazy loading is a great technique to improve your app's performance. The idea of lazy loading is to load a component only when it is needed. React comes bundled with `React.lazy` API so that you can import a dynamic import to regular component.

For example,

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

```

React.lazy takes a function that must call a dynamic import(). This will then return a Promise which resolves to a module with a default export containing a React component.

Another way is to load components only when they are in the viewport. You can use this awesome library `react-loadable-visibility`.

```
import LoadableVisibilty from 'react-loadable-visibility/react-loadable';
import MyLoader from './my-loader-component'

const LoadableComponent = LoadableVisibilty({
    loader:() => import('./my-component'),
    loading:MyLoader
});

export default function APP(){
    return <LoadableComponent/>
}

```

### 🍁Suspense

![Lazy Loading.png](https://cdn.hashnode.com/res/hashnode/image/upload/v1661931600965/IWjNifttU.png)

**Note:** Suspense is an experimental feature at this time. Experimental features may change significantly and without a warning before they become a part of React.

Suspense is an another technique used for lazy loading. It lets you "wait" for some code to load and lets you declaratively specify a loading state while waiting. Multiple lazy components can be wrapped with the suspense component. It takes a fallback property that accepts the react elements you want to render as the lazy component is being loaded.

```
// install the experimental version
npm install react@experimental react-dom@experimental

import React,{Component, lazy, Suspense} from 'react'
const MyComp = lazy(()=>import('../mycomp'))
<Suspense fallback={<div>Loading...</div>}>
<div>
    <MyComp></MyComp>    
</div>

```

- Suspense is most popularly used for waiting for the data
- But it can also be used to wait for images, script or any asynchronous code.
- It helps you avoid race conditions 
  - Race conditions are bug that happen due to incorrect assumptions about the order in which our code can run.
  - Suspense feels more like reading data synchronously -- as if it was already loaded.

### 🍁Suspense - Data Fetching

- It is used to wait for rendering component until the required data is fetched.
  - That means no need to add conditional code anymore!
- You need to enable `concurrent mode`.
  - So the rendering is not blocked.
  - This gives better user experience.

```

// enable concurrent mode 
const rootEl = document.getElementById('root')

//ReactDOM.render(<APP/>, rootEl)
const root = ReactDom.createRoot(rootEl) //you'll use a new createRoot API

root.render(<APP/>)

```

### 🍁Render-as-you-Fetch

This approach doesn't wait for the response to come back before we start rendering. We start rendering pretty much immediately after kicking off the network request.

- Start fetching
- Start rendering
- finish fetching

```
const resource = fetchCartData();

function CartPage(){
    return (
        <Suspense fallback={<h1>Loading Cart...</h1>}>
            <CartDetails/>
        </Suspense>
    );
}
function CartDetails(){
    //Try to read product info, although it might not have loaded yet
    const product = resource.product.read();
    return <h1>{product.name}</h1>
}

```

The `CartPage()` is loaded. It tries to load `CartDetails()`, but `CartDetails()` makes call to `resource.product.read()` so this component `suspenses`. React shows the fallback loader and keep fetching the data in the background. When all the data is retrieved the fallback loader is replaced by `CartDetails()` children.

## 🍀Memoization

![Lazy Loading (1).png](https://cdn.hashnode.com/res/hashnode/image/upload/v1661931796640/vcq4IPbeK.png)

Memoizing in React is a performance feature of the framework that aims to speed up the render process of component. It is a well know concept in programming, aiming to speed up the program by caching results of the expensive function and re-using those cached result as to avoid rendering of expensive function again.

![Lazy Loading (2).png](https://cdn.hashnode.com/res/hashnode/image/upload/v1661935070366/ImRjAmClU.png)

_Memoization in React is not guarantee that your function will be cached_

### 🍁When to use it?

Suppose your state object is updating but your value is not really changing, you can use `memo` to not re-render your functional component. If your component just takes primitive value as props, just wraps it in `memo()` to prevent an unwanted re-render.

React.memo() by default just compares the top-level props. It is not that simple for nested objects. For nested objects, you can pass custom comparer function to check if prop values are same.

```
export default React.memo((props)=>{
    return (<div>{props.val}</div>)
})

//for nested object
const MemoedElement = React.memo(Element, areEqual) 

export function areEqual(prevProps: props, nextProps:props){
    const cardId = nextProps.id
    const newActiveCardId = nextProps.newActiveCardId
    const isActive = newActiveCardId == cardId

    return !some([
        isActive,
    ])
}

```

### 🍁useMemo

`React.memo` is used to memoize components. You can use `useMemo` to memoize inner variable. If there's CPU intensive operation going on to calculate those variables, and the variables does not really change that often then you can use `useMemo`.

```
const allItems = getItems()
//CPU intensive logic
const itemCategories = useMemo(()=> getUniqueCategories(allItems),[allItems])

```

## 🍀Points to remember

- Measure performance using these tools
  - Chrome dev tools
```
- Play with the throttle feature
- Check out the performance timeline and flame charts

```
  - Chrome's Lighthouse tool
- Minimise unnecessary component re-renders
  - use shouldComponentUpdate where applicable
  - use PureComponent
  - use `React.memo` for functional components
```
- along with the ```useMemo()``` hook

```
  - use `React.lazy` if you not doing server-side rendering
  - use `service worker` to cache files that are worth caching
  - use libraries like `react-snap` to pre-render components

Thanks for reading. Like for more such blogs. Happy coding💗