コンテンツにスキップ

loading.js

特別なファイルであるloading.jsは、React Suspense で意味のあるローディングUIを作成するのに役立ちます。この規約により、ルートセグメントのコンテンツがストリーミングされる間、サーバーからインスタントローディングステートを表示できます。新しいコンテンツは完了すると自動的に置き換えられます。

Loading UI
app/feed/loading.tsx
export default function Loading() {
  // Or a custom loading skeleton component
  return <p>Loading...</p>
}

loading.js ファイル内には、軽量なローディングUIを追加できます。React Developer Tools を使用して、Suspense境界を手動で切り替えると便利かもしれません。

デフォルトでは、このファイルはサーバーコンポーネントですが、"use client" ディレクティブを使用してクライアントコンポーネントとしても使用できます。

リファレンス

Parameters

ローディングUIコンポーネントはパラメータを受け取りません。

動作

  • フォールバックUIはプリフェッチされ、プリフェッチが完了していない場合を除き、ナビゲーションは即時実行されます。
  • ナビゲーションは中断可能であり、ルートのコンテンツが完全にロードされるのを待つことなく、別のルートにナビゲートできます。
  • 共有レイアウトは、新しいルートセグメントがロードされている間もインタラクティブなままです。

インスタントローディングステート

インスタントローディングステートとは、ナビゲーション時に即座に表示されるフォールバックUIです。スケルトンやスピナーのようなローディングインジケーター、またはカバー写真やタイトルなど、将来の画面の小さくも意味のある部分を事前レンダリングできます。これにより、ユーザーはアプリが応答していることを理解でき、より良いユーザーエクスペリエンスを提供できます。

ローディングステートを作成するには、フォルダ内にloading.jsファイルを追加します。

loading.js special file
app/dashboard/loading.tsx
export default function Loading() {
  // You can add any UI inside Loading, including a Skeleton.
  return <LoadingSkeleton />
}

同じフォルダ内のloading.jslayout.js内にネストされます。これはpage.jsファイルとそれ以下のすべての子要素を<Suspense>境界で自動的にラップします。

loading.js overview

SEO

  • Twitterbotのように、JavaScriptをフルブラウザのように実行できない、静的HTMLのみをスクレイピングするボットのために、Next.jsはUIのストリーミング前にgenerateMetadataを解決し、メタデータは初期HTMLの<head>に配置されます。
  • それ以外の場合は、ストリーミングメタデータが使用される場合があります。Next.jsはユーザーエージェントを自動的に検出して、ブロッキングとストリーミングの動作を選択します。
  • ストリーミングはサーバーレンダリングされるため、SEOに影響しません。Googleのrobots metaタグに関するガイダンスを参照して、Googleのウェブクローラーから見たページの見え方を確認し、シリアライズされたHTML(ソース)を表示するために、Googleのリッチリザルトテストツールを使用できます。

ステータスコード

ストリーミング時、リクエストが成功したことを示すために200ステータスコードが返されます。

サーバーは、たとえばredirectnotFoundを使用する場合、ストリーミングコンテンツ自体内でクライアントにエラーや問題を通知できます。レスポンスヘッダーはすでにクライアントに送信されているため、レスポンスのステータスコードは更新できません。

たとえば、404ページがクライアントにストリーミングされる場合、Next.jsはストリーミングHTMLに<meta name="robots" content="noindex">タグを含めます。これにより、HTTPステータスが200であっても、検索エンジンがそのURLをインデックスしないようにします。Googleのrobots metaタグに関するガイダンスを参照してください。

一部のクローラーは、これらのレスポンスを「ソフト404」とラベル付けする場合があります。ストリーミングの場合、ページはHTMLで明示的にnoindexとマークされているため、インデックス化につながりません。

コンプライアンスや分析のために404ステータスが必要な場合は、レスポンスボディがストリーミングされる前にリソースが存在することを確認してください。これにより、サーバーがHTTPステータスコードを設定できます。

このチェックはproxyで実行して、欠落したスラッグをnot-foundルートにリライトしたり、404レスポンスを生成したりできます。プロキシチェックは高速に保ち、そこで完全なコンテンツの取得を避けてください。

レスポンスボディはいつストリーミングされますか?

レスポンスボディは、Suspenseフォールバック(例:loading.tsx)がレンダリングされるとき、またはSuspense境界の下でサーバーコンポーネントがサスペンドするときにストリーミングを開始します。notFound()をこれらの境界の前、およびサスペンドする可能性のある任意のawaitの前に配置してください。

ストリーミングを開始するには、レスポンスヘッダーを設定する必要があります。このため、ストリーミング開始後にステータスコードを変更することはできません。

ブラウザの制限

一部のブラウザはストリーミングレスポンスをバッファリングします。レスポンスが1024バイトを超えないと、ストリーミングレスポンスが表示されない場合があります。これは通常、「hello world」アプリケーションにのみ影響し、実際のアプリケーションには影響しません。

プラットフォームのサポート

デプロイメントオプションサポート
Node.jsサーバーはい
Dockerコンテナはい
静的エクスポートいいえ
アダプタープラットフォーム固有

Next.jsをセルフホスティングする際のストリーミングの設定方法を学習してください。

Suspense によるストリーミング

loading.jsに加えて、独自のUIコンポーネントのためにSuspense境界を手動で作成することもできます。App RouterはSuspenseによるストリーミングをサポートしています。

<Suspense>は、非同期アクション(例:データ取得)を実行するコンポーネントをラップし、それが実行されている間はフォールバックUI(例:スケルトン、スピナー)を表示し、アクションが完了するとコンポーネントに置き換えることで機能します。

app/dashboard/page.tsx
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を使用することで、以下のメリットが得られます。

  1. ストリーミングサーバーレンダリング - HTMLをサーバーからクライアントに段階的にレンダリングします。
  2. 選択的ハイドレーション - Reactは、ユーザーの操作に基づいて、どのコンポーネントを最初にインタラクティブにするかを優先します。

Suspenseのさらに詳しい例とユースケースについては、Reactドキュメントを参照してください。

バージョン履歴

バージョン変更履歴
v13.0.0loadingが導入されました。