Learnitweb

React.lazy

What is Code-Splitting?

Code-splitting is a technique that breaks a large JavaScript bundle into smaller chunks. Instead of loading the entire application at once, it loads only the necessary code when required.

Why is this important?

  • Improves Initial Load Time: The browser doesn’t have to download a huge JS file at once.
  • Faster Performance: Unused code is not loaded until needed, reducing memory usage.
  • Optimized User Experience: Users interact with the app without waiting for unnecessary components to load.

How Code-Splitting Works in React

React automatically supports code-splitting through dynamic imports and React.lazy.

  • Instead of bundling everything in a single monolithic JavaScript file, the app splits into separate bundles (chunks).
  • These bundles are loaded on demand when a user navigates to a new page or interacts with a specific component.

lazy lets you defer loading component’s code until it is rendered for the first time.

const SomeComponent = lazy(load)

Call lazy outside your components to declare a lazy-loaded React component:

import { lazy } from 'react';

const MarkdownPreview = lazy(() => import('./MarkdownPreview.js'));

Parameters

  • load: A function that returns a Promise or another thenable (a Promise-like object with a then method). React will not call load until the first time you attempt to render the returned component. After React first calls load, it will wait for it to resolve, and then render the resolved value’s .default as a React component. Both the returned Promise and the Promise’s resolved value will be cached, so React will not call load more than once. If the Promise rejects, React will throw the rejection reason for the nearest Error Boundary to handle.

Returns 

lazy returns a React component you can render in your tree. While the code for the lazy component is still loading, attempting to render it will suspend. Use <Suspense> to display a loading indicator while it’s loading.

Example: Lazy Loading a Component

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

// Lazy load the Home component
const Home = lazy(() => import("./Home"));

const App: React.FC = () => {
  return (
    <div>
      <h1>Welcome to My App</h1>

      {/* Wrap with Suspense to show fallback while loading */}
      <Suspense fallback={<h2>Loading Home...</h2>}>
        <Home />
      </Suspense>
    </div>
  );
};

export default App;

Now, Home loads only when needed!

  • lazy(() => import("./Home")) → Dynamically imports the Home component.
  • Suspense with fallback={<h2>Loading Home...</h2>} → Displays a loading message until Home is ready.

Handling Multiple Lazy Components

You can use React.lazy to load multiple components separately.

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

// Lazy load multiple components
const Home = lazy(() => import("./Home"));
const About = lazy(() => import("./About"));

const App: React.FC = () => {
  return (
    <div>
      <h1>Welcome to My App</h1>

      <Suspense fallback={<h2>Loading components...</h2>}>
        <Home />
        <About />
      </Suspense>
    </div>
  );
};

export default App;

Both Home and About will load separately, reducing initial load time.

Using React.lazy with React Router

When using React Router, you can lazy load routes dynamically, so they only load when accessed.

import React, { lazy, Suspense } from "react";
import { BrowserRouter as Router, Routes, Route, Link } from "react-router-dom";

// Lazy load components
const Home = lazy(() => import("./Home"));
const About = lazy(() => import("./About"));

const App: React.FC = () => {
  return (
    <Router>
      <nav>
        <Link to="/">Home</Link> | <Link to="/about">About</Link>
      </nav>

      <Suspense fallback={<h2>Loading page...</h2>}>
        <Routes>
          <Route path="/" element={<Home />} />
          <Route path="/about" element={<About />} />
        </Routes>
      </Suspense>
    </Router>
  );
};

export default App;

Now, pages load only when visited, improving performance.