loading.js
特殊ファイル loading.js は、React Suspenseを使用して意味のあるLoading UIを作成するのに役立ちます。この規約により、ルートセグメントのコンテンツがストリーミングされている間、サーバーからインスタントローディング状態を表示できます。完了すると、新しいコンテンツが自動的に置き換わります。
export default function Loading() {
// またはカスタムローディングスケルトンコンポーネント
return <p>Loading...</p>
}loading.js ファイル内では、軽量なLoading UIを追加できます。React Developer Toolsを使用してSuspense境界を手動で切り替えると便利かもしれません。
デフォルトでは、このファイルはServer Componentですが、"use client" ディレクティブを使用してClient Componentとしても使用できます。
リファレンス
パラメータ
Loading UIコンポーネントはパラメータを受け入れません。
動作
ナビゲーション
- フォールバックUIはプリフェッチされるため、プリフェッチが完了していない場合を除き、ナビゲーションは即座に行われます。
- ナビゲーションは中断可能です。つまり、ルートを変更するときにルートのコンテンツが完全に読み込まれるのを待つ必要がありません。
- 共有レイアウトは、新しいルートセグメントが読み込まれている間、対話性を維持します。
インスタントローディング状態
インスタントローディング状態は、ナビゲーション時に即座に表示されるフォールバックUIです。スケルトンやスピナーなどのローディングインジケーター、または将来の画面の小さいながら意味のある部分(カバー写真、タイトルなど)を事前にレンダリングできます。これにより、ユーザーはアプリが応答していることを理解でき、より良いユーザー体験が提供されます。
ローディング状態を作成するには、フォルダ内に loading.js ファイルを追加します。
export default function Loading() {
// Loading内に任意のUIを追加できます。Skeletonを含むこともできます。
return <LoadingSkeleton />
}同じフォルダ内では、loading.js は layout.js 内にネストされます。自動的に page.js ファイルと下のすべての子を <Suspense> 境界でラップします。
SEO
- Twitterbotなど、フルブラウザのようにJavaScriptを実行できない静的HTMLのみをスクレイピングするボットの場合、Next.jsはストリーミングUIの前に
generateMetadataを解決し、メタデータは初期HTMLの<head>に配置されます。 - それ以外の場合は、ストリーミングメタデータが使用される可能性があります。Next.jsは自動的にユーザーエージェントを検出して、ブロッキング動作とストリーミング動作の間で選択します。
- ストリーミングはサーバーレンダリングされるため、SEOに影響しません。GoogleのRich Results Testツールを使用して、ページがGoogleのウェブクローラーにどのように表示されるか、およびシリアル化されたHTMLを確認できます(出典)。
ステータスコード
ストリーミング時、リクエストが成功したことを通知するために 200 ステータスコードが返されます。
サーバーは、例えばredirectやnotFoundを使用する場合など、ストリーミングされたコンテンツ自体の中でクライアントにエラーや問題を通信することができます。応答ヘッダーはすでにクライアントに送信されているため、応答のステータスコードを更新することはできません。
例えば、404ページがクライアントにストリーミングされるとき、Next.jsはストリーミングされたHTML内に <meta name="robots" content="noindex"> タグを含めます。これにより、HTTPステータスが200であっても、検索エンジンがそのURLをインデックス化するのを防ぎます。robots メタタグに関するGoogleのガイダンスを参照してください。
一部のクローラーは、これらのレスポンスを「ソフト404」とラベル付けする場合があります。ストリーミングの場合、ページはHTMLで明示的に noindex とマークされているため、インデックス化にはつながりません。
コンプライアンスまたは分析のために404ステータスが必要な場合は、リソースが応答本文がストリーミングされる前に存在することを確認して、サーバーがHTTPステータスコードを設定できるようにします。
このチェックをproxyで実行して、見つからないスラッグをnot-foundルートに書き換えるか、404レスポンスを生成できます。proxyチェックを高速に保ち、そこでフルコンテンツをフェッチすることを避けます。
レスポンス本文がストリーミングされるのはいつですか?
レスポンス本文は、Suspenseフォールバック(例えば、loading.tsx)がレンダリングされるか、Server ComponentがSuspense境界の下でサスペンドするときにストリーミングを開始します。notFound() をそれらの境界の前に、サスペンドする可能性のある await の前に配置します。
ストリーミングを開始するには、レスポンスヘッダーを設定する必要があります。これが、ストリーミング開始後にステータスコードを変更できない理由です。
ブラウザの制限
一部のブラウザはストリーミングレスポンスをバッファリングします。レスポンスが1024バイトを超えるまで、ストリーミングレスポンスが表示されない場合があります。これは通常「hello world」アプリケーションにのみ影響し、実際のアプリケーションには影響しません。
プラットフォームサポート
| デプロイオプション | サポート |
|---|---|
| Node.jsサーバー | はい |
| Dockerコンテナ | はい |
| 静的エクスポート | いいえ |
| アダプター | プラットフォーム依存 |
Next.jsをセルフホスティングする場合のストリーミングの設定方法について説明します。
例
Suspenseでのストリーミング
loading.js に加えて、独自のUIコンポーネント用のSuspense境界を手動で作成することもできます。App RouterはSuspenseでのストリーミングをサポートしています。
<Suspense> は非同期アクション(例:データのフェッチ)を実行するコンポーネントをラップし、その実行中はフォールバックUI(例:スケルトン、スピナー)を表示し、アクションが完了するとコンポーネントに置き換わる仕組みで動作します。
import { Suspense } from 'react'
import { PostFeed, Weather } from './Components'
export default function Posts() {
return (
<section>
<Suspense fallback={<p>Loading feed...</p>}>
<PostFeed />
</Suspense>
<Suspense fallback={<p>Loading weather...</p>}>
<Weather />
</Suspense>
</section>
)
}Suspenseを使用することで、次のメリットが得られます:
- ストリーミングサーバーレンダリング - サーバーからクライアントへHTMLを段階的にレンダリングします。
- 選択的ハイドレーション - Reactはユーザーインタラクションに基づいて、どのコンポーネントを最初に対話性を持たせるかを優先順位付けします。
詳細なSuspenseの例とユースケースについては、Reactのドキュメントを参照してください。
バージョン履歴
| バージョン | 変更内容 |
|---|---|
v13.0.0 | 導入時期:loading。 |