2
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

Next.jsにおけるStreaming機能とは

Last updated at Posted at 2023-08-05

はじめに

こちらはNext.jsにおけるStreaming機能についての記事になります。

よろしければ公式ドキュメントのほうも併せてご覧ください。

Streaming機能を使うメリット

Streaming機能を使うメリットは、ユーザーに対してのレスポンス(HTML返却)を早くすることが可能となることです。

スクリーンショット (2).png

上記はStreaming機能を使わない図を表していますが、例えばNext.jsのサーバー側で非同期通信を行って取得したデータをもとにして生成されるコンポーネントがあった場合、そのコンポーネントが生成されるまでHTMLが返却されないのでユーザービリティが悪くなってしまいます。

その問題はStreaming機能を使うことで解消されます。

スクリーンショット (3).png

上図の青い枠で囲まれたコンポーネントが非同期通信で取得したデータを基にしてコンポーネントが生成されるのですが、非同期通信でNext.jsのサーバー側がコンポーネントを生成している間、デフォルトのコンポーネント(ローディングアイコンなど)をクライアント側に返却しておき、サーバー側のコンポーネントが生成されたらそれをクライアント側に返却して取り替えます。そうすることで初期画面の表示が早くなり、ユーザービリティが向上します。

では次にコードで実際に確認していきたいと思います。

環境構築

gitbash
$ npx create-next-app@latest .

Package.json

スクリーンショット (5).png

ディレクトリ構成

スクリーンショット (4).png

ファイル構成

page.tsx
import { Suspense } from 'react';
import UserList from './UserList';

const Page = async () => {
  return (
    <div className="m-4">
      <h1 className="text-lg font-bold">ユーザ一覧</h1>
      <Suspense fallback={<p>Loading...</p>}>
        <UserList />
      </Suspense>
    </div>
  );
};

export default Page;
UserList.tsx
type User = {
  id: string;
  name: string;
  email: string;
};

const UserList = async () => {
  await new Promise((resolve) => setTimeout(resolve, 5000));
  const response = await fetch('https://jsonplaceholder.typicode.com/users');
  const users: User[] = await response.json();
  return (
    <ul>
      {users.map((user) => (
        <li key={user.id}>{user.name}</li>
      ))}
    </ul>
  );
};

export default UserList;

Streamingの手順

  1. page.tsxとUserList.tsxをsrc/appに作成。
  2. UserListは非同期処理を使って外部API(jsonplaceholder)からデータを取得するコンポーネント。意図的にsetTimeout関数を使い5秒間待機後にデータを取得。
  3. page.tsxはReactのAPIsからSuspenseをインポートし、UserListコンポーネントをラップする。
  4. http://localhost:3000にリクエストを送った時、Suspenceでラップされていないユーザー一覧は表示されるが、UserListは非同期処理のデータが取得されていない為コンポーネントが作成されておらず、fallbackに記述したLoading...が表示される。
    スクリーンショット (1231).png
  5. 5秒後に非同期処理でAPIから取得したデータがUserListに渡ってきて、コンポーネントが生成されクライアント側に送信されて表示される。
    スクリーンショット (1232).png

おわりに

最後まで記事をご覧いただきありがとうございました。

間違いなどありましたらご指摘いただけると幸いです:bow:

参考

2
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?