🧱 Суть

React.lazy + Suspense – это механизм ленивой загрузки компонентов.
Идея: загружать код компонента только тогда, когда он реально нужен

Вместо загрузки всего приложения сразу React может разбить его на отдельные части (chunks) и подгружать их постепенно.

📦 Проблема

Обычный импорт:

import { TabHome } from './TabHome';

добавляет компонент в основной JavaScript-бандл.

То есть:

Открытие сайта
        ↓
загрузка всего кода
        ↓
рендер

Даже если пользователь никогда не откроет вкладку:

<TabProjects />

её код всё равно уже загружен.

✅ Решение

Использовать React.lazy:

const TabHome = lazy(() => import('./TabHome'));

Теперь компонент станет отдельным чанком:

main.js
 |
 ├── TabHome.chunk.js
 ├── TabProjects.chunk.js
 └── TabSkills.chunk.js

Этот файл загрузится только при первом использовании компонента.

💻 Код

Как работает lazy

Код:

const TabProjects = lazy(() => import('./TabProjects'));

означает:

  1. React видит компонент
  2. выполняет динамический import()
  3. браузер загружает отдельный JS-файл
  4. после загрузки React рендерит компонент

Зачем нужен Suspense

Пока компонент загружается, React не может его показать.

Поэтому используется:

<Suspense fallback={<Skeleton />}>
  <CurrentTab />
</Suspense>

Логика:

компонент загружается
        ↓
показать fallback
        ↓
загрузка завершилась
        ↓
показать компонент

Например:

<Suspense fallback={<Loader />}>
  <ProfilePage />
</Suspense>

Пока страница грузится:

[ Loading... ]

После загрузки:

[ Profile Page ]

Зачем это нужно

1. Меньше размер первой загрузки

Без lazy:

app.js
 ├─ главная
 ├─ настройки
 ├─ профиль
 └─ админка

С lazy:

app.js
 └─ главная

запросил настройки → загрузились настройки
запросил профиль → загрузился профиль

2. Быстрее первый запуск приложения

Пользователь получает интерфейс быстрее, потому что браузеру не нужно скачивать весь код сразу.

3. Идеально для больших частей приложения

Чаще всего используют для:

  • страниц
  • маршрутов
  • вкладок
  • модальных окон
  • тяжёлых компонентов

Когда lazy не нужен

Не стоит использовать для маленьких компонентов:

<Button />
<Input />
<Icon />

Причины:

  • они используются постоянно
  • отдельные чанки не дают выгоды
  • появляется лишняя сложность

Также не стоит делать lazy для критических элементов:

  • основной layout
  • главный экран
  • то, что пользователь должен увидеть сразу

🎯 Вывод

  • lazy() создаёт динамический импорт компонента
  • компонент попадает в отдельный chunk
  • загрузка происходит только при первом использовании
  • Suspense показывает fallback во время загрузки
  • идеально подходит для страниц, табов и тяжёлых компонентов
  • уменьшает размер первоначального бандла

🔗 Связано