Skip to main content
Практика завдань

Паралельне та послідовне отримання даних у Next.js

Шаблони отримання даних у Next.js

Як ви структурируєте отримання даних, значно впливає на продуктивність завантаження сторінки. Компоненти сервера Next.js підтримують як паралельні, так і послідовні шаблони.


Послідовне отримання даних (Waterfall)

Кожен запит чекає, поки завершиться попередній:

tsx
// ❌ Послідовне — повільно! Кожен запит чекає на попередній async function UserProfile({ userId }: { userId: string }) { const user = await getUser(userId); // 200ms const posts = await getUserPosts(user.id); // 300ms (чекає на користувача) const followers = await getFollowers(user.id); // 200ms (чекає на пости) // Всього: ~700ms (200 + 300 + 200) return ( <div> <h1>{user.name}</h1> <PostList posts={posts} /> <FollowerList followers={followers} /> </div> ); }

Паралельне отримання даних

Отримуйте всі дані одночасно з Promise.all:

tsx
// ✅ Паралельне — швидко! Усі запити починаються одночасно async function UserProfile({ userId }: { userId: string }) { const [user, posts, followers] = await Promise.all([ getUser(userId), // 200ms getUserPosts(userId), // 300ms (починається одночасно) getFollowers(userId), // 200ms (починається одночасно) ]); // Всього: ~300ms (максимум з усіх трьох) return ( <div> <h1>{user.name}</h1> <PostList posts={posts} /> <FollowerList followers={followers} /> </div> ); }

Паралельне отримання даних на рівні компонентів

Нехай кожен компонент отримує свої дані — Next.js обробляє їх паралельно:

tsx
// Батьківський компонент — без отримання даних тут export default function Dashboard() { return ( <div> <UserStats /> {/* отримує незалежно */} <RecentOrders /> {/* отримує незалежно */} <Notifications /> {/* отримує незалежно */} </div> ); } // Кожен дочірній компонент отримує свої дані async function UserStats() { const stats = await getStats(); // Виконується паралельно з іншими return <StatsCard stats={stats} />; } async function RecentOrders() { const orders = await getOrders(); // Виконується паралельно return <OrderList orders={orders} />; } async function Notifications() { const notifs = await getNotifications(); // Виконується паралельно return <NotifList notifications={notifs} />; }

Стрімінг з Suspense

Показуйте контент поступово в міру надходження даних:

tsx
import { Suspense } from "react"; export default function Dashboard() { return ( <div> {/* Показує відразу */} <h1>Dashboard</h1> {/* Показує скелетон, а потім реальний контент, коли готовий */} <Suspense fallback={<StatsSkeleton />}> <UserStats /> </Suspense> <Suspense fallback={<OrdersSkeleton />}> <RecentOrders /> </Suspense> <Suspense fallback={<NotifsSkeleton />}> <Notifications /> </Suspense> </div> ); }

Переваги стрімінгу:

  • Користувачі бачать контент одразу (немає пустої сторінки)
  • Швидкий контент з'являється першим, повільний контент надходить пізніше
  • Кожен розділ має свій власний стан завантаження

Коли існують залежності

Іноді вам потрібно послідовне отримання:

tsx
async function UserProfile({ userId }: { userId: string }) { // Крок 1: Спочатку потрібно отримати користувача (потрібен user.teamId) const user = await getUser(userId); // Крок 2: Тепер отримуйте паралельно, використовуючи дані користувача const [team, posts] = await Promise.all([ getTeam(user.teamId), // Потрібен user.teamId getUserPosts(user.id), // Потрібен user.id ]); return ( <div> <h1>{user.name}</h1> <TeamInfo team={team} /> <PostList posts={posts} /> </div> ); }

Резюме

ШаблонКолиПродуктивність
ПослідовнийДані залежать від попереднього результатуНайповільніший (waterfall)
Promise.allНезалежні дані в одному компонентіШвидко
Рівень компонентівКожен компонент володіє своїми данимиШвидко + стрімінг
Suspense + стрімінгПоступове завантаженняНайкращий UX

Важливо:

Завжди надавайте перевагу паралельному отриманню при незалежних запитах. Використовуйте Promise.all в одному компоненті або розділіть отримання даних на окремі компоненти. Додавайте межі Suspense для поступового завантаження. Використовуйте послідовне отримання тільки тоді, коли один запит дійсно залежить від результату іншого.

Коротка відповідь

Для співбесіди
Premium

Коротка відповідь допоможе вам впевнено відповідати на цю тему під час співбесіди.

Дочитали статтю?
Практика завдань