Open In App

Mastering Performance Optimization Techniques with React Hooks

Last Updated : 01 Apr, 2024
Improve
Improve
Like Article
Like
Save
Share
Report

In this article, we will explore advanced performance optimization techniques using React Hooks. We’ll delve into memoization, callback optimization, preventing unnecessary renders, state updates, and more. By mastering these techniques, developers can significantly enhance the performance of their React applications.

1. UseMemo:

The useMemo hook in React.js allows you to memorize the result of a function, meaning it caches the output and only re-evaluates the function when its dependencies change. This can improve performance by avoiding unnecessary computations on every render.

Syntax :

const memoizedValue = useMemo(() => {
// Expensive computation or function here
return result;
}, [dependencies]);

Example: Below is the code example:

JavaScript
// index.js 

import React, { useMemo } from 'react';
import ReactDOM from 'react-dom/client';
import './style.css'

function UseMemo() {
    const [count, setCount] = React.useState(0);
    // Simulate an expensive function to generate items
    const generateItems = useMemo(() => {
        const newItems = [];
        for (let i = 0; i < count * 5; i++) {
            newItems.push(`Item ${i + 1}`);
        }
        return newItems;
    }, [count]);

    return (
        <div>
            <p>You clicked {count} times</p>
            <button onClick={() => setCount(prev => prev + 1)}>
                Increment
            </button>
            <ul>
                {generateItems.map((item) => (
                    <li key={item}>{item}</li>
                ))}
            </ul>
        </div>
    );
}

const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
    <div id='main_container'>
        <div>
            <img src=
'https://media.geeksforgeeks.org/gfg-gg-logo.svg' alt='gfg_logo' />
        </div>
        <UseMemo />
    </div>
);

Output:

1711080929553

useMemo project output

2. useCallback

React’s useCallback hook is another tool for performance optimization. Unlike useMemo which caches the result of a function, useCallback focuses on memorizing the function itself. UseCallback allows you to memorize a function, meaning it returns the same function reference as long as its dependencies haven’t changed. Here’s how it helps.

Syntax:

const memoizedFunction = useCallback(() => {
// Function body
}, [dependencies]);

Example: Below is the code example:

JavaScript
// index.js 

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

function ParentComponent(props) {
    const [data, setData] = useState([]);

    const handleClick = useCallback(() => {
        // Perform action using data
    }, [data]);

    return (
        <div>
            <ChildComponent handleClick={handleClick} />
            <button onClick={() => setData([...data, Math.random()])}>
                Add Item
            </button>
            {
                data.map((val) => (
                    <li key={val}>{val}</li>
                ))
            }
        </div>
    );
}

function ChildComponent(props) {
    return <button onClick={props.handleClick}>Click me</button>;
}

const root = ReactDOM.createRoot(
    document.getElementById('root')
);
root.render(
    <div id='main_container'>
        <div>
            <img src=
'https://media.geeksforgeeks.org/gfg-gg-logo.svg' alt='gfg_logo' />
        </div>
        <ParentComponent />
    </div>
);

Output:

1711084427217

useCallback Project Output

3. React.memo

In React, React.memo is a Higher-Order Component (HOC) that helps improve performance by preventing unnecessary re-renders of functional components. It use Memoization technique to optimize the performance of React components by caching the result of the component’s rendering and reusing it if the component’s props remain unchanged. It leads to lower memory usage due to less re-render. Here’s a breakdown of how it works:

Syntax:

const MemoizedComponent = React.memo(FunctionalComponent);

Example: Below is the code example:

JavaScript
// index.js

import React from 'react'

const ListItem = React.memo(({ value }) => {
    console.log(`Rendering item with value: ${value}`);

    return (
        <div>
            <p>Value: {value}</p>
        </div>
    );
});

const List = ({ itemCount = 10 }) => {
    const items =
        Array.from({ length: itemCount }, (_, index) => ({
            id: index,
            value: Math.random() * 1000
            // Generate a random number
        }));

    return (
        <div>
            <h2>List</h2>
            {items.map(item => (
                <ListItem key={item.id} value={item.value} />
            ))}
        </div>
    );
};


const root = ReactDOM.createRoot(
    document.getElementById('root')
);
root.render(
    <div id='main_container'>
        <div>
            <img src=
'https://media.geeksforgeeks.org/gfg-gg-logo.svg' alt='gfg_logo' />
        </div>
        <List />
    </div>
);

Output:

1711086323246

React.memo Browser Output

4. UseEffect:

UseEffect is a powerful hook in React for performing side effects like data fetching, subscriptions, or setting up timers. By specifying dependencies, you can control when the effect runs. If any of the dependencies change between renders, the effect function will be called again and if dependencies array is empty it runs only once. However, if used incorrectly, it can lead to unnecessary re-renders, impacting your application’s performance

Syntax

useEffect(() => {
// Side effect code here
return () => {
// Cleanup code here (optional)
};
}, [dependencies]);

Example: Below is the code example:

JavaScript
// 

function MyComponent(props) {
    const [data, setData] = React.useState(null);

    // Fetches data only once (empty dependency array)
    useEffect(() => {
        fetch('https://api.example.com/data')
            .then((response) => response.json())
            .then((data) => setData(data));
    }, []);

    return (
        <div>
            {data ? (
                <p>Fetched Data: {data.message}</p>
            ) : (
                <p>Loading...</p>
            )}
        </div>
    );
}

5. React Virtualization

Rendering large lists in React can lead to performance issues due to large number of DOM elements being created and managed. React Virtualization is a technique used to optimize the rendering of large lists by only rendering the items that are currently visible on the screen. This significantly reduces the memory footprint and improves the performance of your application.

It is not a part of core React, So you have to install it separately by using the following command.

npm install react-virtualized

Example: Below is the code example:

JavaScript
// index.js 

import React,
{
    useState,
    useEffect
} from 'react';
import { List as VirtualList } from 'react-virtualized';
const LARGE_LIST_SIZE = 1000; // Number of items in the list

function VirtualListComp() {
    const [items, setItems] = useState([]);

    // Simulate data generation (replace with your actual data fetching logic)
    useEffect(() => {
        const newItems = [];
        for (let i = 1; i <= LARGE_LIST_SIZE; i++) {
            newItems.push({ id: i, content: `Item ${i}` });
        }
        setItems(newItems);
    }, []);

    const rowRenderer = ({ index, style }) => {
        const item = items[index];
        return (
            <div key={item.id} style={style}>
                {item.content}
            </div>
        );
    };

    return (
        <div className="App">
            <h1>Large List Example</h1>
            <VirtualList
                width={400}
                height={400}
                rowCount={items.length}
                rowHeight={40} // Height of each item
                rowRenderer={rowRenderer}
            />
        </div>
    );
}

const root = ReactDOM.createRoot(
    document.getElementById('root')
);
root.render(
    <div id='main_container'>
        <div>
            <img src=
'https://media.geeksforgeeks.org/gfg-gg-logo.svg' alt='gfg_logo' />
        </div>
        <VirtualListComp />
    </div>
);

Output:

d3068834-5203-4a9c-9f2a-81136eb07a57-ezgifcom-video-to-gif-converter

React Virtualization Output

6. useRef:

UseRef() is a hook provided by React that creates a mutable reference object which persists across renders of a functional component. It returns a single mutable value object ({current}) that can be updated without causing re-renders. useRef() is commonly used to access or store values that persist between renders without triggering component re-renders.

Example: Below is the code example:

JavaScript
// index.js 

import React, { useRef } from 'react';

const Counter = () => {
    const countRef = useRef(0);
    // Initialize countRef with initial value of 0

    const increment = () => {
        countRef.current += 1;
        // Increment the current value of countRef
        updateCounter();
        // Call updateCounter to update the displayed count
    };

    const reset = () => {
        countRef.current = 0;
        // Reset the current value of countRef to 0
        updateCounter();
        // Call updateCounter to update the displayed count
    };

    const updateCounter = () => {
        // Update the counter displayed in the UI
        document.getElementById('counter').innerText = countRef.current;
    };

    return (
        <div>
            <h2>Counter</h2>
            <p>Count: <span id="counter">
                {countRef.current}
            </span></p>
            <button onClick={increment}>Increment</button>
            <button onClick={reset}>Reset</button>
        </div>
    );
};

const root = ReactDOM.createRoot(
    document.getElementById('root')
);
root.render(
    <div id='main_container'>
        <div>
            <img src=
'https://media.geeksforgeeks.org/gfg-gg-logo.svg' alt='gfg_logo' />
        </div>
        <Counter />
    </div>
);

Output:

9ab80655-1c2f-4122-bc06-19e1112cbafe-ezgifcom-video-to-gif-converter

UseRef Browser Output



Like Article
Suggest improvement
Share your thoughts in the comments

Similar Reads