Lazy loading in Reactjs with React router v6.

Lazy loading in Reactjs with React router v6.

An implementation of lazy loading in Reactjs with React router v6.

Have you ever thought about increasing the performance score of your react application by some percentage? Lazy loading is one of the ways to get that done. How? React provides utility functions that help you to improve performance among other things with lazy loading.

In this article, you would learn about the major advantages of lazy loading and how to implement it in Reactjs.

Prerequisites:

  • Working knowledge of Javascript and React.
  • Basic knowledge of routing in React.

The next section would explain briefly lazy loading and its effect on web applications. Feel free to skip it at your discretion.

Lazy Loading And Its Effects.

How stressful is it for you to carry a 50kg bag from room A to room B in an apartment when you only need the pen inside it? That's exactly what lazy loading defers!

If a user visits the homepage of a website that employs lazy loading to render the pages, only the home page gets rendered because that's what the user wants to see at that moment. The consequence of rendering all the pages on the websites from the server would cause the load time to increase and, in effect, provide a poor experience for the visitor.

In a nutshell, lazy loading is a technique used to render only 'needed' resources and delay the load of the rest until they are requested. Get that?

Why should you use lazy loading in your next react project?

  1. Performance: The performance of your web application or website is subject to but not limited to the number of resources rendered on load. You can add a significant boost to your performance if lazy loading is used to defer unneeded resources and thus reducing the initial load time.

  2. SEO: SEO audits in google chrome's lighthouse capitalize on deferring offscreen images. Why? Every website visitor wants a fast page, the shorter your page load time, the better your SEO. In effect, lazy loading affects all elements of a web page including images.

Other derived advantages include better user experience and better overall score in lighthouse audits - I bet you'd want to have that :)

Now, we've covered the very basics of lazy loading and why it's important. How about we get our hands dirty for a minute?

If you need a refresh on routing in react with react-router-dom, I'd suggest you read through this article before you continue.

Demo React App To Implement Lazy Loading With React Router v6.

In this section, we'd build a simple react application to give you an overview of how it works. Let's get at it! - in the terminal :)

1. Setup your react project.

npx create-react-app lazy-loading-demo

2. Install react-router-dom.

Change your working directory to lazy-loading-demo.

npm install react-router-dom

3. Create a pages folder inside the src/ folder to store the sample pages.

cd src && mkdir pages
cd pages && touch Home.js About.js

4. Create dummy components inside the pages file and export them.

Example:

const Home = () => {
    return(
        <div>
            <h1>Home</h1>
        </div>
    )
};
export default Home;

The same goes for the About.js page.

5. Setup the routes.

We're going to create a separate routes.js file inside the src folder for our routes. This is not necessary, but to avoid clogging our App.js file, let's do it.

touch routes.js

The React.lazy() function will be used inside the routes.js file alongside the dynamic import() to implement lazy loading of our pages in the App.js as follows:

import { lazy } from 'react';

const routes = [
  {
    path: '/',
    exact: true,
    element: lazy(() => import('./pages/Home')),
  },
  {
    path: '/about',
    exact: true,
    element: lazy(() => import('./pages/About')),
  },
];

export default routes;

Okay okay, let me explain a few things here.

The lazy function is what ensures the lazy loading of the pages imported. It takes in a compulsory import() function and returns a promise. The pages are imported 'dynamically' with the import() function to enable code-splitting.

Additionally, the lazy component should be rendered in a Suspense component which allows us to provide a fallback value while we are waiting for the lazy component to load. The fallback value usually is the loading screen you might have come across in large web applications. In our case, we'd keep it simple ...

6. Import the routes in your App.js file.

This is where we implement the chunk in the previous paragraph. In our App.js file, we would import the routes.js file and render the components using the Javascript map function. So, technically, we need to import our routing functions from react-router-dom first, and import the Suspense function from react.

import { Suspense } from 'react';
import { BrowserRouter as Router, Route, Routes} from 'react-router-dom';

And also, we might need a simple navigation menu. I'd suggest we add the Link function to the imports.

Inside our App component,

function App() {
  return (
    <Router>
      <div className="App">
        <nav>
          <ul>
            <li><Link to="/">Home</Link></li>
            <li><Link to="/about">About</Link></li>
          </ul>
        </nav>
      <Routes>
          {routes.map((route, i) => {
            return (
              <Route
                key={i}
                path={route.path}
                element={
                  <Suspense fallback={<>...</>}>
                   <route.element />
                  </Suspense>
                }
              />
            );
          })}
        </Routes>
      </div>
    </Router>

  );
}

What's going on here? Firstly, a few things change in react-router v6.

  1. The Switch is replaced with Routes.
  2. The component props passed into Route was replaced with element.

We returned our routes using the map function and added the Suspense around the element in the element props as required. The Suspense fallback value was a simple ellipse in a Fragment.

Anddd, that's it! That was all we need to implement lazy loading. You can use the same approach in your project if you want or choose to modify it.

Meanwhile, Our final App.js file should be looking like this:

import { Suspense } from 'react';
import { BrowserRouter as Router, Route, Routes, Link} from 'react-router-dom';
import routes from './routes';

function App() {
  return (
    <Router>
      <div className="App">
        <nav>
          <ul>
            <li><Link to="/">Home</Link></li>
            <li><Link to="/about">About</Link></li>
          </ul>
        </nav>
      <Routes>
          {routes.map((route, i) => {
            return (
              <Route
                key={i}
                path={route.path}
                element={
                  <Suspense fallback={<>...</>}>
                   <route.element />
                  </Suspense>
                }
              />
            );
          })}
        </Routes>
      </div>
    </Router>

  );
}

export default App;

Conclusion.

Lazy loading provides significant improvement in the performance of your web application. This article has covered briefly the core benefits of lazy loading and how to implement it in a react application.

If you found this article helpful, let me know in the comment section :)

Till next time 🥂