Современные JavaScript приложения могут быть довольно большими с точки зрения размера bundle пакета. Вам бы не хотелось, чтобы ваши пользователи загружали JavaScript пакет объемом в 1 МБ (ваш код и библиотеки, которые вы используете) только для загрузки первой страницы, верно? Но это то, что происходит по умолчанию, в современном веб-приложении, собраном с помощью Webpack.
Этот пакет будет содержать код, который может никогда и не запуститься, в случае если пользователь останется только на главной странице.
Разделение кода - это практика загрузки только того JavaScript-кода, который вам нужен в определенный момент времени и тогда, когда вам это нужно.
Это улучшает:
- производительность вашего приложения;
- влияние на память, и, следовательно, уменьшает использование батареи на мобильных устройствах;
- размер загруженного файла.
Lazy()
“Ленивая” (Lazy) функция - это функция, которая загружает компонент только в момент, когда он действительно понадобится, а не заранее при загрузке приложения. Это позволяет уменьшить время загрузки и ускорить отклик приложения.
Для создания ленивых компонентов используется функция lazy() из пакета react, которая принимает функцию-импорт компонента и возвращает новый компонент, который будет загружаться лениво.
Пример:
import React, { lazy, Suspense } from "react"
const MyLazyComponent = lazy(() => import("./MyComponent"))
function App() {
return (
<div>
<Suspense fallback={<div>Loading...</div>}>
<MyLazyComponent />
</Suspense>
</div>
)
}В этом примере мы создали компонент MyLazyComponent, который будет загружаться лениво при его первом использовании на странице. Для загрузки компонента мы использовали функцию lazy() и передали ей функцию-импорт компонента.
<Suspense />
Затем мы использовали компонент Suspense для отображения заглушки (fallback) во время загрузки ленивого компонента. Заглушка может быть любым JSX-элементом, который будет отображаться во время загрузки компонента.
<Suspense> позволяет отображать заглушки до тех пор, пока его дочерние элементы не закончат загрузку.
<Suspense fallback={<Loading />}>
<SomeComponent />
</Suspense>props
children: Фактический пользовательский интерфейс, который вы собираетесь рендерить. Еслиchildrenприостановится во время рендеринга, граница Suspense переключится на рендерингfallback.fallback: Альтернативный пользовательский интерфейс, который будет отображаться вместо реального пользовательского интерфейса, если он не закончил загрузку. Принимается любой допустимый узел React, хотя на практике запасной вариант - это легковесное представление-заполнитель, например, загрузочный спиннер или скелет. Приостановка будет автоматически переключаться наfallback, когдаchildrenприостанавливает работу, и обратно наchildren, когда данные будут готовы. Еслиfallbackприостанавливает работу во время рендеринга, он активирует ближайшую родительскую границу Suspense.
Ограничения
- React не сохраняет состояние для рендеров, которые были приостановлены до того, как они смогли смонтироваться в первый раз. Когда компонент загрузится, React повторит попытку рендеринга приостановленного дерева с нуля.
- Если
Suspenseотображал содержимое для дерева, но затем снова приостановился, тооткатбудет показан снова, если только обновление, вызвавшее его, не было вызваноstartTransitionилиuseDeferredValue. - Если React необходимо скрыть уже видимый контент из-за повторного приостановления, он очистит layout Effects в дереве контента. Когда контент снова будет готов к показу, React снова запустит Эффекты компоновки. Это гарантирует, что Эффекты, измеряющие макет DOM, не попытаются сделать это, пока содержимое скрыто.
- React включает в себя такие “подкапотные” оптимизации, как Streaming Server Rendering и Selective Hydration, которые интегрированы в Suspense. Чтобы узнать больше, прочитайте архитектурный обзор и посмотрите технический доклад.