lazy и Suspense

Тема дорожной карты · React

React.lazy() и Suspense — это встроенные API React для реализации разделения кода и декларативных состояний загрузки, позволяющие загружать компоненты лениво из отдельных JavaScript-чанков. React.lazy() принимает функцию, возвращающую динамический промис import(), и создаёт ленивый компонент, который React загружает по требованию при первом рендеринге в дереве. Компонент Suspense оборачивает один или несколько ленивых компонентов и рендерит проп fallback — обычно спиннер или скелетон-экран — пока код ленивого компонента загружается по сети. Вместе React.lazy() и Suspense обеспечивают разделение кода на уровне маршрутов и компонентов с минимальным количеством шаблонного кода, значительно улучшая производительность первоначальной загрузки крупных React-приложений. В React 19 Suspense также интегрируется с библиотеками загрузки данных и React Server Components для обработки асинхронных границ рендеринга, выходящих за рамки просто лениво загружаемого кода.

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

lazy и Suspense — это в основном избегание ненужных ререндеров. React.memo(Component) пропускает ререндер, если props равны по ссылке; парная связка с useMemo/useCallback стабилизирует props. lazy(() => import("./X")) + <Suspense fallback={...}> откладывает загрузку chunk до момента нужды (route-based code splitting). React Profiler (в DevTools) показывает, какой компонент сколько занял и почему ререндерился — читайте перед тюнингом вслепую.

Когда применять

Сначала профайл, потом оптимизация. Lazy-load по route-границе для любого бандла >~200 KB gzipped. Мемоизируйте детей дорогих списков через React.memo + стабильные коллбэки. Windowing (react-window, react-virtualized) — для списков 1000+ элементов. Пропустите useMemo/useCallback для тривиальных значений — оверхед учёта дороже сэкономленного compute в 90% случаев.

Типичные ошибки

Ловушки lazy и Suspense: обёртка каждого компонента в React.memo "для производительности" (стоимость сравнений суммируется — мемоизируйте только листья часто ререндерящихся деревьев); мемоизация значений с дешёвым compute (оверхед больше выгоды); большой бандл без code splitting (медленный TTI); оптимизация без замеров (чините не то). Источник истины — вкладка Profiler в React DevTools.

Связанные понятия

Полезные ресурсы