DEV Community

Cover image for Optimizing User Experience: The Lazy Loading Approach in React"
Yusuf Mubaraq
Yusuf Mubaraq

Posted on • Edited on

Optimizing User Experience: The Lazy Loading Approach in React"

What is lazy loading in Reactjs?

Lazy loading in React is a powerful technique to optimize the performance and efficiency of web applications by delaying the loading of non-essential components until they are actually needed. This method not only enhances the initial load time, making the application feel faster and more responsive to users, but also reduces the overall resource consumption and bandwidth usage. Moreover, lazy loading aligns with best practices in modern web development, such as code splitting and efficient resource management, which are crucial for building scalable and maintainable applications. It also allows for better handling of large applications with complex component structures, ensuring that only the necessary code is delivered to the user at the right time.

Why Do We Implement Lazy Loading?

Imagine we're building a small-scale application with just a few components, such as a homepage, an about page, a contacts page, and some API calls. In a typical setup, all these components and files are bundled into a single JavaScript file, which is then loaded by the browser.

Let's illustrate this with a practical example. Start your React app and open the browser's Developer Tools by right-clicking and selecting "Inspect." Navigate to the "Network" tab, then click on the "JS" tab. Reload the webpage and observe the network activity. Notice which JavaScript files are loaded initially and pay attention to any additional files that load when you interact with the app. In a typical React application, the initial rendering of the webpage is driven by a single JavaScript file. While this approach is straightforward and works well for small applications, it can lead to inefficiencies as the application grows in size and complexity.

Network tab

The big question: Is it suitable to have just one JavaScript file for our entire application?

For small-scale applications with just a few components, having a single JavaScript file might seem acceptable. However, consider large-scale applications like Amazon or eBay, which contain thousands of components and numerous features. If all of this were handled by a single JavaScript file, the file size would become significantly large, leading to increased load times and performance issues.

Therefore, it's crucial to break down the code into multiple JavaScript files or bundles. This approach, known as code splitting, helps optimize the application, improve load times, and enhance user experience. Without implementing such techniques, a large application would suffer from slow performance and other issues.

How Can We Implement This in Our React App?

Let's get started by opening our online code editor. I've already created a React app, set up the folder structure, and installed necessary libraries like react-router-dom for navigation.
In the src folder, I created a components folder containing all the component files. Inside this folder, there is a Homepage component that renders the homepage of the website. We'll focus on the Product component linked in the header, where we will implement the lazy loading feature.

Website homepage

We'll import the Products component into the App.jsx file, which manages all our routing. However, instead of using the standard import, we'll use React's lazy function to achieve this.


import React, { lazy } from “react”;
import {Routes, Route} from “react-router-dom”;

const Product = lazy(()=> import(“./components/Products”));
const App = ()=> {
return(
       <>
         //  //  //
         //  //  //
       </>
    )
}

export default App

Enter fullscreen mode Exit fullscreen mode

Can you see the method we used to import the Products component into the App.jsx file? We created a variable named Products. Note that the first letter is capitalised because it is a component, not a regular variable. The lazy function takes a callback function, which includes the import function. Is this import the same as the standard import statement above? Absolutely not. This is different; it is called a dynamic import. The dynamic import function takes the path to the Products component as its argument.

Now let's go back to our browser and reload the page. Is the Products component visible in our network tab? Absolutely not.

Network Tab

But what if I told you that our JavaScript bundler does not yet include the code for the Products component? It hasn't loaded that code yet. Curious? Now, let's click on the Products link. Can you see the magic that just happened in our Network tab?

Network tab

The Products component responded to our request. This means we're loading the Products page on demand and rendering it on the screen only when it's needed.

But why is our Product page displaying an error? When React attempts to load the page but cannot find the code, it suspends the process by throwing an error. However, there's a solution to this situation. React offers a component called "Suspense" to handle such errors. Let's put it into practice below:


import React, { lazy, Suspense } from “react”;
import {Routes, Route} from “react-router-dom”;

const Product = lazy(()=> import(“./components/Products”));
const App = ()=> {
return(
  <>
   <Routes>
    <Route path=“ / ”   element={<Home/>} />
    <Route path=“ / products ”   element={<Suspense fallback={<div>Loading….<div/>}><Products/><Suspense/>} />
   <Routes/>
 </>
    )
}

export default App

Enter fullscreen mode Exit fullscreen mode

In the code snippet above, we import the Suspense component from React and then wrap it around our Products component. This instructs React to load the Products page only when necessary. Now, what's the purpose of the fallback attribute? As the name suggests, it determines what gets rendered on the screen before the Product component is activated. You can include JSX or a component inside it. Keep in mind that it might not be visible due to how quickly React renders our components on the screen. However, you can test it by slowing down the network or disabling it entirely.

In summary, implementing lazy loading in React is not just a performance optimization; it is a strategic approach to improve the overall user experience, manage application complexity, and ensure efficient use of resources. This makes it an essential tool in the toolkit of any React developer aiming to build high-performing, user-friendly web applications.

Top comments (2)

Collapse
 
akshit_agarwal_5211eff08d profile image
AKSHIT Agarwal

I don't think this is how it should be implemented. This is the react docs for the same: react.dev/reference/react/lazy#tro...

You shoudn't write *const Product = lazy(()=> import(“./components/Products”));
*
inside the component body.

Collapse
 
baraq profile image
Yusuf Mubaraq

Thanks for the correction