Запропонувати правкуПокращити цю статтюДопрацюйте відповідь до «Що робить React.lazy()?». Ваші зміни проходять модерацію перед публікацією.Потрібне підтвердженняКонтентЩо ви змінюєте🇺🇸EN🇺🇦UAПереглядЗаголовок (UA)Коротка відповідь (UA)`React.lazy()` дозволяє завантажувати компонент не одразу при старті, а тільки коли він реально знадобиться (наприклад, при переході на сторінку, відкритті модалки тощо). **Ключове:** `React.lazy()` працює тільки всередині компонента `<Suspense>`, який відповідає за показ "заглушки" (`fallback`) під час завантаження.Показується над повною відповіддю для швидкого нагадування.Відповідь (UA)Зображення## Що робить `React.lazy()` `React.lazy()` дозволяє **завантажувати компонент не одразу при старті**, а **тільки коли він реально знадобиться** (наприклад, при переході на сторінку, відкритті модалки тощо). --- ### Синтаксис: ```javascript const MyComponent = React.lazy(() => import('./MyComponent')); ``` - `React.lazy()` приймає **функцію, що повертає динамічний імпорт** (`import()`). - Цей імпорт повертає **Promise**, який завантажує JS-файл з компонентом. - React сам підвантажить компонент, коли дійде до нього в дереві рендера. --- ## Приклад без `React.lazy` (все вантажиться одразу) ```javascript import HeavyChart from './HeavyChart'; function Dashboard() { return ( <div> <h1>Dashboard</h1> <HeavyChart /> {/* завантажується одразу */} </div> ); } ``` Компонент `HeavyChart` (наприклад, з chart.js або d3) вантажиться **одразу**, навіть якщо він не видимий або поки не потрібен. Стартове завантаження - важке і довге. --- ## Приклад з `React.lazy()` ```javascript import React, { Suspense, lazy } from 'react'; const HeavyChart = lazy(() => import('./HeavyChart')); function Dashboard() { return ( <div> <h1>Dashboard</h1> <Suspense fallback={<div>Завантаження графіка...</div>}> <HeavyChart /> </Suspense> </div> ); } ``` Тепер: - `HeavyChart` **не входить в основний бандл**. - React підвантажить його **тільки при першому рендері**, коли дійде до `<HeavyChart />`. - Поки компонент не завантажений - показується **заглушка з** `fallback` (`<div>Завантаження...</div>`). --- ## Як це працює "під капотом" 1. Коли React зустрічає `<HeavyChart />`: - запускає динамічний імпорт -> `import('./HeavyChart')`; - Webpack / Vite створює **окремий JS-чанк** (наприклад, `HeavyChart.chunk.js`). 2. Поки чанк завантажується - React **показує** `fallback` з `<Suspense>`. 3. Коли завантаження завершено: - React рендерить компонент; - "лінива" частина застосунку стає активною. --- ## Обов'язково обгортати в `<Suspense>` `React.lazy()` **працює тільки всередині компонента** `<Suspense>`, тому що Suspense відповідає за показ "заглушки" під час завантаження: ```javascript <Suspense fallback={<Spinner />}> <LazyComponent /> </Suspense> ``` Без `<Suspense>` React видасть помилку: ```javascript A React component suspended while rendering, but no fallback UI was specified. ``` --- ## Приклад лінивого завантаження сторінок (Routing) Дуже популярний кейс: ```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>Завантаження сторінки...</div>}> <Routes> <Route path="/" element={<Home />} /> <Route path="/dashboard" element={<Dashboard />} /> <Route path="/settings" element={<Settings />} /> </Routes> </Suspense> ); } ``` Тепер кожна сторінка вантажиться **в окремому чанку** - тільки коли користувач дійсно заходить на неї. --- ## Що відбувається при збірці Webpack / Vite розділяють код на чанки: ```javascript main.js Home.chunk.js Dashboard.chunk.js Settings.chunk.js ``` - При завантаженні застосунку завантажується **тільки** `main.js`. - Коли користувач переходить на `/dashboard` -> React робить `GET Dashboard.chunk.js`. - Таким чином, стартове завантаження стає **набагато швидшим**. --- ## Коли варто використовувати `React.lazy()` Чудово підходить для: - сторінок і маршрутів (routing); - модальних вікон і діалогів; - важких компонентів (таблиці, графіки, редактори, карти); - панелей налаштувань і вкладок, які рідко відкриваються; - адмінок і SPA, де не все потрібно одразу. --- ## Коли **не потрібно** використовувати `React.lazy()` Надмірне використання може шкодити UX: - якщо компонент **маленький і легкий** - краще вантажити одразу; - якщо компонент **майже завжди потрібен** (наприклад, `Header`, `NavBar`); - якщо потрібен SSR (серверний рендерінг) - `React.lazy()` працює тільки на клієнті (потрібні інші рішення, наприклад `next/dynamic`). --- ## Порівняння "до" і "після" | Поведінка | Без `React.lazy()` | З `React.lazy()` | |---|---|---| | Завантаження | Всі компоненти одразу | Тільки за потреби | | Розмір стартового JS | Великий | Менший | | Стартова швидкість | Повільніша | Швидша | | Fallback | Немає | З'являється під час завантаження | | Підтримка SSR | Є | Тільки в клієнтському рендері | --- ## Як комбінувати з prefetch/preload Можна заздалегідь "попередньо завантажити" чанк при наведенні, щоб зробити перехід миттєвим: ```javascript const LazySettings = lazy(() => import('./Settings')); function Nav() { const handleMouseEnter = () => import('./Settings'); // prefetch return <button onMouseEnter={handleMouseEnter}>Налаштування</button>; } ``` React не буде рендерити компонент одразу, але файл `Settings.chunk.js` завантажиться заздалегідь. --- ## Підсумок | Що робить | Як допомагає | |---|---| | Відкладене завантаження компонентів | Ділить код на чанки | | Прискорює завантаження застосунку | Менший стартовий JS | | Працює з `<Suspense>` | Показує fallback під час завантаження | | Простий у використанні | `const Comp = lazy(() => import('./Comp'))` | | Завантажує "за вимогою" | Тільки коли компонент реально потрібен | --- **Простими словами:** > `React.lazy()` - це спосіб сказати React: > "Не завантажуй цей компонент одразу - підвантаж, коли він знадобиться користувачу."Для рев’юераПримітка для модератора (необов’язково)Бачить лише модератор. Прискорює рев’ю.