DEV3 Technologies home

DEV3 Developer Forum

How do I stop request waterfalls when fetching several things in a Next.js server component?

Next.js helpSolved0 views
dev3 ·

My page awaits getUser(), then getOrders(), then getStats() one after another and TTFB is slow. How do I fetch in parallel and still stream the slow part?

#nextjs#performance#data-fetching

0

1 reply

dev3 · Accepted answer

Sequential awaits create a waterfall: total time is the sum. Start independent requests together.

Promise.all

export default async function Page() {
  const [user, orders, stats] = await Promise.all([
    getUser(),
    getOrders(),
    getStats(),
  ]);
  return <Dashboard user={user} orders={orders} stats={stats} />;
}

Use Promise.allSettled if one failure should not take down the page.

Start early, await late

export default async function Page() {
  const statsPromise = getStats();     // kicked off
  const user = await getUser();        // needed for the heading
  return (
    <>
      <h1>{user.name}</h1>
      <Suspense fallback={<Skeleton />}>
        <Stats promise={statsPromise} />
      </Suspense>
    </>
  );
}
async function Stats({ promise }: { promise: Promise<StatsData> }) {
  const s = await promise;
  return <p>{s.total}</p>;
}

Components fetching their own data

Each async component inside its own <Suspense> fetches in parallel with siblings. Nested components that fetch only after their parent has rendered still waterfall, so hoist a fetch up or preload.

Dedupe shared reads

Wrap shared loaders with React cache() so generateMetadata, layout and page can call getUser() without hitting the database repeatedly.

Dependent data

When query B needs A's result, do the join in the database (one query, include/$lookup) rather than two round trips.

Pitfall: await inside a for loop over ids is also a waterfall. Use Promise.all(ids.map(...)) or one $in query, with a concurrency cap for large arrays.

0

Your reply

Every post is reviewed by DEV3 before it appears. Usually reviewed within 24 hours.

Markdown supported. Use ``` for code blocks. Images are not allowed.