Panda Noir

JavaScript の限界を究めるブログでした。最近はいろんな分野を幅広めに書いてます。

Next.js で layout をネストしたときパフォーマンスはどうなるのか?

Next.js で作ったアプリの /foo にアクセスすると app/layout.tsx と app/foo/layout.tsx の両方が適用されます。

さて、このネストされた2つの layout それぞれでデータフェッチをしていた場合、どうなるでしょうか?

  • app/layout.tsx のフェッチ完了後に app/foo/layout.tsx のフェッチが始まる
  • app/foo/layout.tsx のフェッチ完了後に app/layout.tsx のフェッチが始まる
  • 同時に app/layout.tsx のフェッチと app/foo/layout.tsx のフェッチが始まる

ぱっと聞かれて分かりますか?僕は分からなかったので リポジトリ を実際に作って検証してみました。

答え: 同時に app/layout.tsx のフェッチと app/foo/layout.tsx のフェッチが始まる

答えは 「同時に始まる」 です。 検証に使ったリポジトリ

実例

以下のコードを実行したときにかかる時間は max(getSession() の時間, fetchUserData() の時間) になります。getSession() の時間 + fetchUserData() の時間 ではありません。

// app/layout.tsx
import { setTimeout } from 'timers/promises';
import { getSession } from '@auth/nextjs-auth0';

export default async function RootLayout({
  children,
}: {
  children: React.ReactNode;
}) {
  const user = await getSession();
  return (
    <html lang="en">
      <body>
        <h1>hello {user.name}</h1>
        <div>{children}</div>
      </body>
    </html>
  );
}
import { setTimeout } from 'timers/promises';
import { fetchUserData } from './fetchUserData';

export default async function RootLayout({
  children,
}: {
  children: React.ReactNode;
}) {
  const data = await fetchUserData();
  return (
    <div>
      <h2>data: {data}</h2>
      <div>{children}</div>
    </div>
  );
}