跳至內容
建置您的應用程式 (Building Your Application)路由 (Routing)載入 UI 和串流 (Loading UI and Streaming)

載入 UI 與串流

特殊檔案 loading.js 可協助您使用 React Suspense 建立有意義的載入 UI。透過此慣例,您可以在路由區段內容載入時,從伺服器顯示即時載入狀態。渲染完成後,新內容會自動替換。

Loading UI

即時載入狀態 (Instant Loading States)

瞬間載入狀態是一種在導覽後立即顯示的後備 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.js 將被嵌套在 layout.js 內。它會自動將 page.js 檔案和其下的任何子元件包裝在 <Suspense> 邊界內。

loading.js overview

注意事項:

  • 即使使用以伺服器為中心的路由,導覽也是即時的。
  • 導覽是可以中斷的,這意味著更改路由不需要等待路由的內容完全載入才能導覽到另一個路由。
  • 在載入新的路由區段時,共用的佈局仍保持互動性。

建議:針對路由區段(佈局和頁面)使用 loading.js 慣例,因為 Next.js 會最佳化此功能。

使用 Suspense 串流

除了 loading.js 之外,您也可以手動為您自己的 UI 元件建立 Suspense 邊界。應用程式路由器支援使用 Suspense 進行串流,適用於 Node.js 和 Edge 執行環境

注意事項:

  • 某些瀏覽器 會緩衝串流回應。您可能要等到回應超過 1024 位元組才會看到串流的回應。這通常只會影響「hello world」應用程式,而不會影響實際應用程式。

什麼是串流?

要了解串流在 React 和 Next.js 中的運作方式,了解**伺服器端渲染 (SSR)** 及其限制會有所幫助。

使用 SSR 時,使用者在看到頁面並與之互動之前,需要完成一系列步驟

  1. 首先,在伺服器上擷取指定頁面的所有資料。
  2. 然後,伺服器會渲染頁面的 HTML。
  3. 頁面的 HTML、CSS 和 JavaScript 會傳送到用戶端。
  4. 使用產生的 HTML 和 CSS 顯示非互動式使用者介面。
  5. 最後,React 會注水(hydrate)使用者介面,使其具有互動性。
Chart showing Server Rendering without Streaming

這些步驟是依序且阻塞的,也就是說,伺服器只有在所有資料都擷取完成後才能渲染頁面的 HTML。而在客戶端,React 也只能在頁面中所有元件的程式碼都下載完成後才能注水 UI。

使用 React 和 Next.js 的伺服器端渲染 (SSR) 有助於提升感知載入效能,它會盡快向使用者顯示一個非互動式的頁面。

Server Rendering without Streaming

然而,它仍然可能很慢,因為伺服器上的所有資料擷取都需要在頁面顯示給使用者之前完成。

串流允許您將頁面的 HTML 分解成更小的區塊,並逐步將這些區塊從伺服器發送到客戶端。

How Server Rendering with Streaming Works

這使得頁面的部分內容可以更快地顯示,而無需等待所有資料載入後才能渲染任何 UI。

串流與 React 的元件模型可以很好地搭配運作,因為每個元件都可以被視為一個區塊。具有較高優先順序的元件(例如產品資訊)或不依賴資料的元件(例如佈局)可以先發送,而 React 可以更早開始注水。具有較低優先順序的元件(例如評論、相關產品)可以在其資料擷取完成後,在同一個伺服器請求中發送。

Chart showing Server Rendering with Streaming

當您想要防止長時間的資料請求阻塞頁面渲染時,串流特別有用,因為它可以減少首位元組時間 (TTFB)首次內容繪製 (FCP)。它還有助於提升互動時間 (TTI),尤其是在速度較慢的裝置上。

範例

<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 文件

SEO

  • Next.js 會在將 UI 串流到用戶端之前,等待 generateMetadata 內的資料擷取完成。這確保了串流回應的第一部分包含 <head> 標籤。
  • 由於串流處理是在伺服器端渲染的,因此它不會影響 SEO。您可以使用 Google 的 豐富結果測試 工具來查看您的網頁在 Google 網路爬蟲中的顯示方式,並檢視序列化後的 HTML (來源)。

狀態碼 redirectnotFound 時。由於回應標頭已經發送到用戶端,因此無法更新回應的狀態碼。這不影響 SEO。