Suggest an editImprove this articleRefine the answer for “What does React.lazy() do?”. Your changes go to moderation before they’re published.Approval requiredContentWhat you’re changing🇺🇸EN🇺🇦UAPreviewTitle (EN)Short answer (EN)`React.lazy()` lets you load a component not right at startup, but only when it's actually needed (for example, on navigating to a page, opening a modal, etc.). **Key point:** `React.lazy()` only works inside a `<Suspense>` component, which is responsible for showing a "placeholder" (`fallback`) while loading.Shown above the full answer for quick recall.Answer (EN)Image## What `React.lazy()` does `React.lazy()` lets you **load a component not right at startup**, but **only when it's actually needed** (for example, on navigating to a page, opening a modal, etc.). --- ### Syntax: ```javascript const MyComponent = React.lazy(() => import('./MyComponent')); ``` - `React.lazy()` accepts a **function that returns a dynamic import** (`import()`). - This import returns a **Promise** that loads the JS file with the component. - React loads the component itself once it reaches it in the render tree. --- ## Example without `React.lazy` (everything loads right away) ```javascript import HeavyChart from './HeavyChart'; function Dashboard() { return ( <div> <h1>Dashboard</h1> <HeavyChart /> {/* loads immediately */} </div> ); } ``` The `HeavyChart` component (for example, using chart.js or d3) loads **right away**, even if it's not visible or not needed yet. The startup load is heavy and slow. --- ## Example with `React.lazy()` ```javascript import React, { Suspense, lazy } from 'react'; const HeavyChart = lazy(() => import('./HeavyChart')); function Dashboard() { return ( <div> <h1>Dashboard</h1> <Suspense fallback={<div>Loading chart...</div>}> <HeavyChart /> </Suspense> </div> ); } ``` Now: - `HeavyChart` **isn't part of the main bundle**. - React loads it **only on the first render** that reaches `<HeavyChart />`. - While the component isn't loaded, a **placeholder from** `fallback` is shown (`<div>Loading...</div>`). --- ## How this works "under the hood" 1. When React encounters `<HeavyChart />`: - it triggers a dynamic import -> `import('./HeavyChart')`; - Webpack / Vite creates a **separate JS chunk** (for example, `HeavyChart.chunk.js`). 2. While the chunk is loading, React **shows** the `fallback` from `<Suspense>`. 3. Once loading is finished: - React renders the component; - the "lazy" part of the app becomes active. --- ## You must wrap it in `<Suspense>` `React.lazy()` **only works inside a** `<Suspense>` component, because Suspense is responsible for showing a "placeholder" while loading: ```javascript <Suspense fallback={<Spinner />}> <LazyComponent /> </Suspense> ``` Without `<Suspense>` React will throw an error: ```javascript A React component suspended while rendering, but no fallback UI was specified. ``` --- ## Example of lazy-loading pages (Routing) A very popular case: ```javascript import { lazy, Suspense } from 'react'; import { Routes, Route } from 'react-router-dom'; const Home = lazy(() => import('./pages/Home')); const Dashboard = lazy(() => import('./pages/Dashboard')); const Settings = lazy(() => import('./pages/Settings')); function App() { return ( <Suspense fallback={<div>Loading page...</div>}> <Routes> <Route path="/" element={<Home />} /> <Route path="/dashboard" element={<Dashboard />} /> <Route path="/settings" element={<Settings />} /> </Routes> </Suspense> ); } ``` Now every page loads **in a separate chunk** - only when the user actually navigates to it. --- ## What happens at build time Webpack / Vite split the code into chunks: ```javascript main.js Home.chunk.js Dashboard.chunk.js Settings.chunk.js ``` - When the app loads, only `main.js` is loaded. - When the user navigates to `/dashboard` -> React does a `GET Dashboard.chunk.js`. - This way, the startup load becomes **much faster**. --- ## When to use `React.lazy()` Great for: - pages and routes (routing); - modal windows and dialogs; - heavy components (tables, charts, editors, maps); - settings panels and tabs that are opened rarely; - admin panels and SPAs where not everything is needed right away. --- ## When you **don't need** `React.lazy()` Overusing it can hurt UX: - if the component is **small and light**, it's better to load it right away; - if the component is **almost always needed** (for example, `Header`, `NavBar`); - if you need SSR (server-side rendering) - `React.lazy()` only works on the client (other solutions are needed, such as `next/dynamic`). --- ## Comparing "before" and "after" | Behavior | Without `React.lazy()` | With `React.lazy()` | |---|---|---| | Loading | All components at once | Only when needed | | Startup JS size | Large | Smaller | | Startup speed | Slower | Faster | | Fallback | None | Shown during loading | | SSR support | Yes | Only in client rendering | --- ## How to combine it with prefetch/preload You can "preload" the chunk in advance on hover, to make the transition instant: ```javascript const LazySettings = lazy(() => import('./Settings')); function Nav() { const handleMouseEnter = () => import('./Settings'); // prefetch return <button onMouseEnter={handleMouseEnter}>Settings</button>; } ``` React won't render the component right away, but the `Settings.chunk.js` file will be loaded in advance. --- ## Summary | What it does | How it helps | |---|---| | Deferred loading of components | Splits code into chunks | | Speeds up app loading | Smaller startup JS | | Works with `<Suspense>` | Shows a fallback while loading | | Simple to use | `const Comp = lazy(() => import('./Comp'))` | | Loads "on demand" | Only when the component is actually needed | --- **In simple terms:** > `React.lazy()` is a way to tell React: > "Don't load this component right away - load it when the user actually needs it."For the reviewerNote to the moderator (optional)Visible only to the moderator. Helps review go faster.