テックブログ | GoodFunctionの技術や開発を発信
Next.js : ストリーミングを活用してユーザー体験を向上させる

Next.js : ストリーミングを活用してユーザー体験を向上させる

  • Next.js
Next.js : ストリーミングを活用してユーザー体験を向上させる

伴野 太一朗

2024.02.23

こんにちは!グッドファンクションの伴野です。
今回はNext.jsのストリーミングについて説明したいと思います。
ストリーミングを活用すれば、取得に時間のかかるデータを後から表示させることができ、ユーザー体験の向上につながります。
Next.jsを使っている方はぜひご覧ください。

SSR(サーバーサイドレンダリング)の問題点

サーバーサイドでレンダリングを行うSSRは、CSR(クライアントサイドレンダリング)よりもページ読み込みが早い・SEOに有効などのメリットがあります。
また、ユーザー側のデバイスに依存しないため読み込みが安定します。

しかしSSRにも問題点があります。
それは、時間のかかる処理があった場合に、ページ表示までに時間がかかってしまうことです。通常のSSRでは、レンダリング結果を一括でレスポンスするため、ページ読み込みの遅延が発生してしまいます。
ユーザーからは画面が止まったように見えてしまうため、ユーザーエクスペリエンスの観点から対策が必要です。


ストリーミングで対策

この問題の対策としては、ストリーミングが有効です。
Next.jsのストリーミングは、特定のデータを後からレスポンスする転送技術です。
これにより、すべてのデータが読み込まれるのを待たずに、ページの一部を先に表示することができます。

(参考 : Next.js 公式チュートリアル)


Next.jsにおけるストリーミングの方法は二つあります。

  • ページ全体ストリーミング(loading.tsx)

  • コンポーネントストリーミング(Suspense)

ページ全体ストリーミング(loading.tsx)

loading.tsxを各ルーティング階層のトップに配置することで、レンダリングが完了するまでの間、画面全体がストリーミングされます。
これはローディング画面と同じ意味となります。

import DashboardSkeleton from '@/app/ui/skeletons'; 

export default function DashboardLoading() {  
  return <DashboardSkeleton />;
}


ちなみに弊社のテックブログでも同様の対応をしていますが、loading.tsxの配置は下記のようにしています。

root/
src/
  └app/
    └ (tech_blog)/
      └ tech_blog/
        └ loading.tsx  <- 一覧画面用のローディング
        └ page.tsx
[id]/
          └ loading.tsx  <- 詳細画面用のローディング
          └ page.tsx
      └ layout.tsx



ページがレンダリングされるまでの間は、スケルトンが表示されます。


コンポーネントストリーミング(Suspense)

特定の部分をストリーミングしたい場合は、React Suspense を使用します。
これにより、アプリケーションのレンダリングを部分的に遅延できます。

ストリーミングしたいコンポーネントをSuspenseで囲みます。
fallback={} にはストリーミングまでの間に表示させるスケルトンコンポーネントを渡します。

import { Suspense } from 'react';
import { Detail } from '~/app/_components/detail/Detail';
import { DetailSkelton } from '~/app/_components/detail/DetailSkelton';

export default function DetailPage() {
  return (
    <>
      <h1>詳細ページ</h1>
      <div>
        <Suspense fallback={<DetailSkelton />}>
          <Detail />
        </Suspense>
      </div>
    </>
  );
}


データの取得はコンポーネント内で行います。

import {fetchDetail} from '~/app/...';

export async function Detail() {
  const detail = await fetchDetail(); // データの取得
  
  return (
    // データを表示する...
  );
}

上記の対応ができると、特定のコンポーネントを遅延表示させることができます。

(参考 : Next.js 公式チュートリアル)

さいごに

今回はNext.jsのストリーミングについての説明となりましたが、いかがだったでしょうか。
ストリーミングを使用することでユーザー体験の向上につながるので、ぜひ活用してみてください。
またグッドファンクションでは、Next.jsの開発・相談を承っております。
ご興味のある方はぜひお問合せください。


参考

Next.js | Streaming