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

Мгновенные состояния загрузки
Мгновенное состояние загрузки — это резервный интерфейс, который отображается сразу при навигации. Вы можете предварительно рендерить индикаторы загрузки, такие как скелетоны и спиннеры, или небольшие, но значимые части будущих экранов, например обложку, заголовок и т.д. Это помогает пользователям понять, что приложение реагирует, и улучшает пользовательский опыт.
Создайте состояние загрузки, добавив файл 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 для своих компонентов. App Router поддерживает потоковую передачу с Suspense для сред выполнения Node.js и Edge.
Полезно знать:
- Некоторые браузеры буферизуют потоковый ответ. Вы можете не увидеть потоковый ответ, пока он не превысит 1024 байта. Обычно это затрагивает только "hello world" приложения, но не реальные проекты.
Что такое потоковая передача?
Чтобы понять, как работает потоковая передача в 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. Вы можете использовать инструмент Rich Results Test от Google, чтобы увидеть, как ваша страница выглядит для веб-краулеров Google, и просмотреть сериализованный HTML (источник).
Коды состояния
При потоковой передаче возвращается код состояния 200
, указывающий на успешность запроса.
Сервер всё ещё может сообщать об ошибках или проблемах клиенту внутри самого потокового контента, например, при использовании redirect
или notFound
. Поскольку заголовки ответа уже отправлены клиенту, код состояния ответа не может быть обновлён. Это не влияет на SEO.