how to optimize react application

Methods of How to Improving and Optimizing Performance in React Application

Let’s discuss how to optimize react application

Introduction on how to optimize react application

Performance is a key element in the quality of an application. It depends on how we write the code and configure the infrastructure.

Performance optimization is a vital factor to be considered before deploying an application.

It’ll influence the user experience.

During this article, we’ll explore other ways to optimize React’s performance.

Let’s have a Look!

Hire ReactJS Developer

Overview of how to optimize react application

The performance of a website or web application is measured objectively and is based on the user’s experience.

Web performance usually concerns reducing the size of the files without affecting code functionality.

There are some key features available in react, that you want to enhance the performance of the application.

As well, as some basic standards, you wish to follow.

Like, such as code reusability, optimized code, etc. to enhance your web performance.

Using Pure Components

If a React component returns the same output for the same state and props, it’s declared pure.

React provides the “PureComponent” base class for class components. Components that expand the React framework.

The PureComponent class is treated as if it were a single component.

It’s the same as a regular component, only PureComponents handles shouldComponentUpdate — it performs a shallow comparison of the state and props data.

The component is not re-rendered if the previous state and props data are the same as the next props or state.

What is shallow rendering?

A shallow comparison will ensure that primitives have the same value and that references between more complicated JavaScript values like objects and arrays are the same when comparing previous props and states to the next.

It is less expensive to compare primitive and object references than to update the component view.

As a result, rather than generating needless updates, searching for changes in state and props’ values will be faster.

import React from "react";

class RegularComponent extends React.Component {
  render() {
    console.log("regular component called", this.props.name);
    return <div>Regular Component {this.props.name}</div>;
  }
}

class PureComponent extends React.PureComponent {
  render() {
    console.log("regular component called", this.props.name);
    return <div>Pure Component {this.props.name}</div>;
  }
}

class ParentComponent extends React.Component {
  constructor(props) {
    super(props);

this.state = {
    name: "Kaushal"
  };
}

componentDidMount() {
  setInterval(() => {
    this.setState({
      name: "Kaushal"
    });
  }, 2000);
}

render() {
  console.log("------------- parent component ------------");
  return (
    <>
      <div>Parent Component</div>
      <PureComponent name={this.state.name} />
      <RegularComponent name={this.state.name} />
    </>
   );
  }
}

export default ParentComponent;

The state is propagated to the child components RegularComponent and PureComponent in the example above.

PureComponent is a pure component.

The setState method is invoked after a one-second interval, which re-triggers the component’s view rendering.

The component (PureComponent) will not be re-rendered because the initial and updated props values are the same.

Because there is no change in the data for either props or state in a shallow comparison of the state, the component does not need to be rendered, making it more effective.

React components how to optimize

React.memo

React.memo is a higher-order component. It has been introduced in React v16.6.

It is similar to a PureComponent, but PureComponent belongs to the class Component, whereas memo is used for the creation of functional components.

If your component renders the same result given the same props, you can wrap it in a call to React.memo for a performance boost in some cases by memoizing the result.

This means that React will skip rendering the component, and reuse the last rendered result.

import React, { memo, useEffect, useState } from "react";

const RegularComponent = ({ name }) => {
  console.log("regular component called", name);
  return <div>Regular Component {name}</div>;
}

const MemoComponent = memo(({ name }) => {
  console.log("memo component called", name);
  return <div>Memo Component {name}</div>;
})

const ParentMemoComponent = () => {
  const [state, setState] = useState({ name: "Kaushal" });

useEffect(() => {
  setInterval(() => {
    setState({ name: "Kaushal" })
  }, [2000])
}, [])

console.log("------------- parent component ------------");
return (
  <>
    <div>Parent Component</div>
    <MemoComponent name={state.name} />
    <RegularComponent name={state.name} />
  </>
 );
}

export default ParentMemoComponent;

In the above example, the Regular component will render every time the state changes.

But In MemoComponent, the whole component is wrapped with a memo. Using that prevents unnecessary rendering if there is no change in the Parent State component.

React.memo

React.useMemo

It is a hook that memorizes the return value of a function.

It is used to reduce unnecessary rendering. That takes 2 arguments, a function and an array which is called a dependency array.

The function is called initially or if any change array value. In case the dependency array has changed then it will return a new reference.

If we do not pass any dependency then it’ll have the same reference value. If we didn’t pass the second argument dependency array to useMemo then it’ll render every time.

import { useState, useMemo } from 'react'

function ReactUseMemo() {

  const [input, setInput] = useState('')
  const [count, setCount] = useState(0);

  const doubleCountWithMemo = useMemo(() => {
    console.log("useMemo called");
      return doubleMyCount(count)
}, [count])

const doubleCountWithReg = () => {
  console.log("Reg called");
  return doubleMyCount(count)
}

const dbCount = doubleCountWithReg()

return (
    <div style={{
  display: 'flex', 
  flexDirection: 'column', 
  justifyContent: 'center', 
  width: '25%', margin: 'auto'
}}>
    <h2>UseMemo vs Reg variable</h2>
    <input value={input} onChange={(e) => setInput(e.target.value)} />
    <button onClick={() => setCount(prevCount => prevCount + 1)}> count: {count}
   </button>
  Double count with useMemo= {doubleCountWithMemo}
  <br/>
  Double Count With Reg = {dbCount}
  </div>
 );
}

const doubleMyCount = (count) => {
  // for delay generation
  for (let i = 0; i < 1000000000; i++) { }
  return count * 2
}

export default ReactUseMemo;

In the above example, Initially, both the regular function and useMemo hook function will render initially.

If we press the count button then the state count will change and having the same dependency useMemo hook will render the function and return a new reference value to the variable doubleCountWithMemo at the same time another regular function will be called.

But If we make changes in input then doubleCountWithMemo will not render as there is no change in the dependency array. But the regular function doubleCountWithReg will be called every time as input changes. You can find the result below:

React.useMemo

React.useCallback

React useCallback works the same as useMemo but it returns a function instead of a variable.

If dependency changes then it’ll create a function with a new reference. If dependency will not change then the function will have the same reference.

useCallback Hook will be used to avoid unnecessary rendering.

import React, { useState, useCallback } from 'react';

const ReactuseCallback = () => {
  const [count, setCount] = useState(0);
  console.log("re-render parent component");

  const resetCount = useCallback(() => {
    setCount(0);
  }, [setCount]);

  const resetCountBtn = () => {
    setCount(0);
  };

return (
    <main>
      <p>Count: {count}</p>
         <button 
             onClick={() => setCount(count => (count + 1))}
           >
         Increment
       </button>
      <UseCallbackChild reset={resetCount} />
     <RegularFnChild reset={resetCountBtn} />
    </main>
  )
}

export default ReactuseCallback

const UseCallbackChild = React.memo(({ reset }) => {
     console.log("re-render use-selector child component.")
     return (
        <div>
          <p>UseCallbackChild component which resets count</p>
          <button onClick={reset}>Reset Count</button>
        </div>
      );
   });

const RegularFnChild = React.memo(({ reset }) => {
     console.log("re-render regular function child component.")
     return (
        <div>
            <p>RegularFnChild component which resets count</p>
            <button onClick={reset}>Reset Count</button>
        </div>
    );
 })

In the above example, We are passing functions to child components but one component has a callback function while another component has a regular function. And both components are wrapped with React.memo.

When one can press the increment button Regular component child will re-render but the UseCallbackChild component will not re-render as the reference of the function will not change due to UseCallback.

React.useCallback

0 replies

Leave a Reply

Want to join the discussion?
Feel free to contribute!

Leave a Reply