React Course
React
/
Advanced

Code Splitting & Lazy Loading

Definition

Code splitting is a feature supported by bundlers like Webpack and Vite that allows you to split your code into various bundles which can then be loaded on demand (lazily). React supports this natively using `React.lazy()` and `<Suspense>`.

Explain Like I'm New

Imagine you are going on a hike. You *could* pack a massive backpack with a tent, a winter coat, a swimsuit, and 30 days of food (sending the entire JavaScript app at once). But that makes the initial hike (page load) incredibly slow and heavy! Code splitting is like magic teleportation. You only pack a water bottle (the Home page code). When you reach a lake and need a swimsuit, you press a button, and the swimsuit is instantly downloaded to your backpack. You only download the code you actually need, exactly when you need it.

Real World Example

Your app has a massive 'Admin Dashboard' full of heavy charting libraries (like Chart.js). 99% of your users are regular customers who never see the dashboard. If you don't code-split, all users are forced to download the charting library, making their page load slower. With `React.lazy()`, only Admins who actually click the 'Dashboard' button will trigger the download of that specific code.

Common Use Cases

  • Reducing the Initial Page Load time (Time to Interactive)
  • Splitting code based on React Router routes (Route-based splitting)
  • Isolating massive 3rd-party dependencies

Interactive Example

import React, { Suspense } from 'react';

// 1. Standard Import (Bundled immediately)
import Header from './Header'; 

// 2. Dynamic Import / Lazy Load (Split into a separate bundle)
// This component and all of its heavy dependencies won't be downloaded
// until the 'Show Heavy Dashboard' button is clicked and it actually renders.
const HeavyDashboard = React.lazy(() => import('./HeavyDashboard'));

export default function App() {
  const [showDashboard, setShowDashboard] = React.useState(false);

  return (
    <div>
      {/* Loads immediately because it was statically imported */}
      <Header />
      
      <button onClick={() => setShowDashboard(true)}>
        Show Heavy Dashboard
      </button>

      {showDashboard && (
        // 3. We MUST wrap lazy components in Suspense
        <Suspense fallback={<h2>Downloading dashboard code... please wait.</h2>}>
          <HeavyDashboard />
        </Suspense>
      )}
    </div>
  );
}

Interview Questions

basic

  • What is the main benefit of Code Splitting?
  • How do you dynamically import a component in React?

intermediate

  • What is `React.lazy()` used for?
  • Why must `React.lazy()` be used in conjunction with `<Suspense>`?

advanced

  • Can you use `React.lazy()` for Server-Side Rendering (SSR)?
  • How do you implement route-based code splitting?

trick

  • Can you use `React.lazy()` with Named Exports (e.g., `export const MyComponent`)?

Flash Cards

Question

Why must React.lazy be used with Suspense?

Click to reveal answer
Answer

When a lazily loaded component is first rendered, the code hasn't downloaded yet. React needs to know what to display on the screen while it waits for the network request to finish. `<Suspense fallback={<Spinner/>}>` tells React what to show during that delay.

Question

Can you use React.lazy() for Server-Side Rendering?

Click to reveal answer
Answer

No. `React.lazy()` and Suspense for code-splitting do not work during standard SSR. If you are using an SSR framework like Next.js, you must use their specific dynamic import functions (e.g., `next/dynamic`).

Question

Can you use React.lazy() with Named Exports?

Click to reveal answer
Answer

Currently, `React.lazy()` only supports Default Exports. If the component you want to import uses a named export, you must create an intermediate module that re-exports it as the default, or use a workaround like `import().then(module => ({ default: module.MyComponent }))`.