UI загрузки и потоковая передача данных
Специальный файл loading.js
помогает создавать информативный UI загрузки с использованием React Suspense. С этим соглашением вы можете показывать мгновенное состояние загрузки с сервера, пока загружается контент сегмента маршрута. Новый контент автоматически заменяется после завершения рендеринга.

Мгновенные состояния загрузки
Мгновенное состояние загрузки — это запасной UI, который отображается сразу при навигации. Вы можете предварительно рендерить индикаторы загрузки, такие как скелетоны и спиннеры, или небольшие, но значимые части будущих экранов, например обложку, заголовок и т.д. Это помогает пользователям понять, что приложение реагирует, и улучшает пользовательский опыт.
Создайте состояние загрузки, добавив файл loading.js
в папку.

export default function Loading() {
// Внутрь Loading можно добавить любой UI, включая скелетон.
return <LoadingSkeleton />
}
export default function Loading() {
// Внутрь Loading можно добавить любой UI, включая скелетон.
return <LoadingSkeleton />
}
В той же папке loading.js
будет вложен в layout.js
. Он автоматически обернет файл page.js
и все дочерние элементы в границу <Suspense>
.

Полезно знать:
- Навигация происходит мгновенно, даже с сервероцентричной маршрутизацией.
- Навигация прерываема, что означает возможность перехода на другой маршрут без ожидания полной загрузки текущего.
- Общие макеты остаются интерактивными во время загрузки новых сегментов маршрута.
Рекомендация: Используйте соглашение
loading.js
для сегментов маршрута (макетов и страниц), так как Next.js оптимизирует эту функциональность.
Потоковая передача с Suspense
Помимо loading.js
, вы также можете вручную создавать границы Suspense для своих UI-компонентов. App Router поддерживает потоковую передачу с Suspense для сред выполнения Node.js и Edge.
Что такое потоковая передача?
Чтобы понять, как работает потоковая передача в React и Next.js, полезно разобраться в рендеринге на стороне сервера (SSR) и его ограничениях.
При SSR есть последовательность шагов, которые должны быть выполнены перед тем, как пользователь увидит и сможет взаимодействовать со страницей:
- Сначала все данные для страницы загружаются на сервере.
- Затем сервер рендерит HTML для страницы.
- HTML, CSS и JavaScript для страницы отправляются клиенту.
- Пользователю показывается неинтерактивный интерфейс на основе сгенерированного HTML и CSS.
- Наконец, React гидратирует интерфейс, делая его интерактивным.

Эти шаги последовательны и блокирующие, что означает, что сервер может рендерить HTML только после загрузки всех данных. А на клиенте React может гидратировать UI только после загрузки кода всех компонентов страницы.
SSR с React и Next.js помогает улучшить воспринимаемую скорость загрузки, показывая пользователю неинтерактивную страницу как можно быстрее.

Однако это всё равно может быть медленным, так как все данные должны быть загружены на сервере перед показом страницы.
Потоковая передача позволяет разбить HTML страницы на меньшие части и постепенно отправлять их с сервера на клиент.

Это позволяет отображать части страницы раньше, не дожидаясь загрузки всех данных перед рендерингом любого UI.
Потоковая передача хорошо сочетается с компонентной моделью React, так как каждый компонент можно рассматривать как отдельную часть. Компоненты с высоким приоритетом (например, информация о продукте) или не зависящие от данных могут быть отправлены первыми (например, макет), и React может начать гидратацию раньше. Компоненты с низким приоритетом (например, отзывы, связанные товары) могут быть отправлены в том же запросе после загрузки их данных.

Потоковая передача особенно полезна, когда нужно избежать блокировки рендеринга страницы из-за длительных запросов данных, так как это может уменьшить Time To First Byte (TTFB) и First Contentful Paint (FCP). Она также улучшает Time to Interactive (TTI), особенно на медленных устройствах.
Пример
<Suspense>
работает, оборачивая компонент, выполняющий асинхронное действие (например, загрузку данных), показывая запасной UI (например, скелетон, спиннер) во время выполнения действия, а затем заменяя его вашим компонентом после завершения.
import { Suspense } from 'react'
import { PostFeed, Weather } from './Components'
export default function Posts() {
return (
<section>
<Suspense fallback={<p>Загрузка ленты...</p>}>
<PostFeed />
</Suspense>
<Suspense fallback={<p>Загрузка погоды...</p>}>
<Weather />
</Suspense>
</section>
)
}
import { Suspense } from 'react'
import { PostFeed, Weather } from './Components'
export default function Posts() {
return (
<section>
<Suspense fallback={<p>Загрузка ленты...</p>}>
<PostFeed />
</Suspense>
<Suspense fallback={<p>Загрузка погоды...</p>}>
<Weather />
</Suspense>
</section>
)
}
Используя Suspense, вы получаете преимущества:
- Потоковый серверный рендеринг — Постепенная отправка HTML с сервера на клиент.
- Избирательная гидратация — React приоритизирует, какие компоненты сделать интерактивными в первую очередь, основываясь на взаимодействии пользователя.
Больше примеров и случаев использования Suspense можно найти в документации React.
SEO
- Next.js будет ждать завершения загрузки данных внутри
generateMetadata
перед потоковой передачей UI клиенту. Это гарантирует, что первая часть ответа включает теги<head>
. - Поскольку потоковая передача выполняется на сервере, она не влияет на SEO. Вы можете использовать инструмент Mobile Friendly Test от Google, чтобы увидеть, как ваша страница выглядит для веб-краулеров Google, и просмотреть сериализованный HTML (источник).
Коды состояния
При потоковой передаче возвращается код состояния 200
, указывающий на успешность запроса.
Сервер всё ещё может сообщать об ошибках или проблемах клиенту внутри передаваемого контента, например при использовании redirect
или notFound
. Поскольку заголовки ответа уже отправлены клиенту, код состояния ответа не может быть изменён. Это не влияет на SEO.