Next.js

Lesson 06

Parallel data fetching

Start independent data requests before awaiting them to avoid waterfalls.

Good Code

app/projects/[projectId]/page.tsx
import { getProject, getReviewSummary } from "@/lib/projects";

export default async function ProjectPage({
  params,
}: PageProps<"/projects/[projectId]">) {
  const { projectId } = await params;
  // Start independent requests before awaiting so rendering waits once.
  const projectPromise = getProject(projectId);
  const summaryPromise = getReviewSummary(projectId);
  const [project, summary] = await Promise.all([
    projectPromise,
    summaryPromise,
  ]);

  return (
    <section>
      <h1>{project.name}</h1>
      <p>{summary.openCount} open reviews</p>
    </section>
  );
}

Bad Code

app/projects/[projectId]/page.tsx
import { getProject, getReviewSummary } from "@/lib/projects";

export default async function ProjectPage({
  params,
}: PageProps<"/projects/[projectId]">) {
  const { projectId } = await params;
  // Awaiting each independent request in order creates a server-side waterfall.
  const project = await getProject(projectId);
  const summary = await getReviewSummary(projectId);

  return (
    <section>
      <h1>{project.name}</h1>
      <p>{summary.openCount} open reviews</p>
    </section>
  );
}

Review Notes

What to review

Good Code

The good version starts both independent requests before waiting, so the route waits for the slower request rather than the sum of both.

Bad Code

The bad version awaits each request in sequence even though the second request does not depend on the first result.

Takeaways

  • Independent server requests should be initiated together, then awaited together.