Published on

How to Speed ​​Up React Apps

In this article, I will guide you on how to speed up your React apps in the most effective way.
How to Speed ​​Up React Apps
Authors
  • Name
    Nguyen Pham

Overview

React is the most popular JavaScript library today, developed and maintained by Facebook. It helps us build web applications easily and quickly. However, optimizing React applications to increase page loading speed is a problem that many developers face.

In this article, we will not talk about configuring optimization tools such as Webpack, Vite... but will focus on optimizing React source code to increase page loading speed.

Using useCallback

Let's look at the following code snippet:

jsx
export default function Demo() {
    const toggleTheme = () => {
        if (theme === "dark") {
            setTheme("light");
        }
    };

    return (
        <button onClick={() => toggleTheme()}>Toggle Theme</button>
    );
}

Improve it with useCallback:

jsx
import { useCallback } from "react";

export default function Demo() {
    const toggleTheme = useCallback(() => {
        if (theme === "dark") {
            setTheme("light");
        }
    }, [theme, setTheme]);
    
    return (
        <button onClick={toggleTheme}>Toggle Theme</button>
    );
}

With this way, React will not have to create a new function every time the component is re-rendered, helping to reduce memory usage and increase page loading speed.

Using useMemo

Similar to useCallback, useMemo helps us optimize React source code by storing previously calculated values.

jsx
export default function Demo() {
    return (
        <BlockBG
            bgImage="/imgs/madelab/homepagebg.jpg"
        />
    );
}

Improve it with useMemo:

jsx
import { useMemo } from "react";

export default function Demo() {
    const blockBGProps = useMemo(() => ({
        bgImage: "/imgs/madelab/homepagebg.jpg",
    }), []);

    return (
        <BlockBG {...blockBGProps} />
    );
}

Thus, React will not have to create a new object every time the component is re-rendered, everything will be stored in memory.

Change the way to import

Instead of importing all components from the React library:

jsx
import BlockNewletters from "./BlockNewletters";
export default function Demo() {
    return (
        <>
            ...
            <BlockNewletters />
            ...
        </>
    )
}

Let's import each component directly:

jsx
import React, { useEffect, useState, useCallback } from "react";
import BlockNewletters from "./BlockNewletters";

const MemoizedBlockNewletters = React.memo(BlockNewletters);

export default function Demo() {
    return (
        <>
            ...
            <MemoizedBlockNewletters />
            ...
        </>
    )
}

With this way, React will not have to load the entire React library every time it renders a component. Instead, it only loads the necessary components first.

Using React.memo

React.memo helps us optimize React source code by storing the previously rendered result.

jsx
import { Modal } from "antd";

export default function Demo() {
    return (
        <Modal
            open={isModalOpen === "autosubscribe"}
        >
        </Modal>
    )
}

Improve it with:

jsx
import React, { useCallback } from "react"; 
import { Modal } from "antd";

const MemoizedModal = React.memo(Modal);

export default function Demo() {
    return (
        <MemoizedModal
            open={isModalOpen === "autosubscribe"}
        >
        </MemoizedModal>
    )
}

If-Else syntax

Instead of using the if-else syntax:

jsx
{loading && (
    <Loading />
)}
{!loading && (
    <Content />
)}

Use a shorter syntax:

jsx
{loading ? <Loading /> : <Content />}

Using lazy and Suspense

React provides lazy and Suspense to load components when needed.

jsx
import BlockEditor from "@/app/components/block-editor";

export default function Demo() {
    return (
        <BlockEditor />
    )
}

Improve it with:

jsx
import React, { lazy, Suspense } from "react";

export default function Demo() {
    const LazyBlockEditor = memo(lazy(() => import("@/app/components/block-editor")));

    return (
        <Suspense fallback={<>Loading...</>}>
            <LazyBlockEditor />
        </Suspense>
    )
}

Working with loops

Instead of using a regular loop:

jsx
export default function Demo() {
    return (
        <>
            {items.map((item, index) => (
                <Item key={index} item={item} />
            ))}
        </>
    )
}

Use the following method:

jsx
import { useMemo } from "react";

export default function Demo() {
    const socialIcons = useMemo(() => {
        return items.map((item, index) => (
            <Item key={index} item={item} />
        ));
    }, [items]);

    return (
        <>
            {socialIcons}
        </>
    )
}

With this way, React will not have to recalculate every time the component is re-rendered.

Working with Font render

Instead of using fonts from FontAwesome:

jsx
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";

export default function Demo() {
    return (
        <FontAwesomeIcon icon={faCoffee} className="icon" style={{ color: "red" }} />
    )
}

Use the following method:

jsx
import { useMemo } from "react";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";

const MemoizedFontAwesomeIcon = React.memo(FontAwesomeIcon);

const iconProps = useMemo(() => ({
    className: "icon",
    style: { color: "red" }
}), []);

export default function Demo() {
    return (
        <MemoizedFontAwesomeIcon {...iconProps} icon={faCoffee} />
    )
}

Caching API requests

Instead of calling the API every time the component is re-rendered:

jsx
import { useEffect, useState } from "react";

export default function Demo() {
    const [data, setData] = useState([]);

    useEffect(() => {
        fetch("https://api.blog.nguyenpham.pro/posts")
            .then(res => res.json())
            .then(data => setData(data));
    }, []);

    return (
        <>
            {data.map((item, index) => (
                <Item key={index} item={item} />
            ))}
        </>
    )
}

Use the following method:

jsx
import { useCallback, useEffect, useState, useMemo } from "react";

export default function Demo() {
    const [data, setData] = useState([]);
    const fetchData = useCallback(() => {
        fetch("https://api.blog.nguyenpham.pro/posts", { cache: "force-cache" })
            .then(res => res.json())
            .then(data => setData(data));
    }, []);
    const memoizedData = useMemo(() => data, [data]);

    useEffect(() => {
        fetchData();
    }, [fetchData]);

    return (
        <>
            {memoizedData.map((item, index) => (
                <Item key={index} item={item} />
            ))}
        </>
    )
}

Conclusion

The above are some ways to optimize React source code to increase page loading speed. I hope this article will help you optimize your React application. If you have any questions or comments, please leave a message. Wish you success!

Nguyen Pham

Nguyen Pham

Làm việc tại phòng thí nghiệm MADE, Texas, USA. Là một người đam mê với công nghệ và thích chia sẻ kiến thức với mọi người.

Nguyen Pham — là nhà phát triển và thiết kế giàu kinh nghiệm tập trung vào WordPress, NextJS, Angular. Hãy xem một số dự án chúng tôi đã thực hiện và các sản phẩm nội bộ của chúng tôi.
Liên kết
Made by VueJS and Vercel Cloud· All rights reserved.