はじめに
こちらはNext.jsにおけるStreaming機能についての記事になります。
よろしければ公式ドキュメントのほうも併せてご覧ください。
Streaming機能を使うメリット
Streaming機能を使うメリットは、ユーザーに対してのレスポンス(HTML返却)を早くすることが可能となることです。
上記はStreaming機能を使わない図を表していますが、例えばNext.jsのサーバー側で非同期通信を行って取得したデータをもとにして生成されるコンポーネントがあった場合、そのコンポーネントが生成されるまでHTMLが返却されないのでユーザービリティが悪くなってしまいます。
その問題はStreaming機能を使うことで解消されます。
上図の青い枠で囲まれたコンポーネントが非同期通信で取得したデータを基にしてコンポーネントが生成されるのですが、非同期通信でNext.jsのサーバー側がコンポーネントを生成している間、デフォルトのコンポーネント(ローディングアイコンなど)をクライアント側に返却しておき、サーバー側のコンポーネントが生成されたらそれをクライアント側に返却して取り替えます。そうすることで初期画面の表示が早くなり、ユーザービリティが向上します。
では次にコードで実際に確認していきたいと思います。
環境構築
$ npx create-next-app@latest .
Package.json
ディレクトリ構成
ファイル構成
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;
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の手順
- page.tsxとUserList.tsxをsrc/appに作成。
- UserListは非同期処理を使って外部API(jsonplaceholder)からデータを取得するコンポーネント。意図的にsetTimeout関数を使い5秒間待機後にデータを取得。
- page.tsxはReactのAPIsから
Suspense
をインポートし、UserListコンポーネントをラップする。 -
http://localhost:3000
にリクエストを送った時、Suspence
でラップされていないユーザー一覧
は表示されるが、UserListは非同期処理のデータが取得されていない為コンポーネントが作成されておらず、fallback
に記述したLoading...
が表示される。
- 5秒後に非同期処理でAPIから取得したデータがUserListに渡ってきて、コンポーネントが生成されクライアント側に送信されて表示される。
おわりに
最後まで記事をご覧いただきありがとうございました。
間違いなどありましたらご指摘いただけると幸いです
参考