跳到主要内容

加载 UI 和流式处理

特殊文件 loading.js 可以帮助您使用 React Suspense 创建有意义的加载 UI。 通过这种约定,您可以在路由段的内容加载时显示 即时加载状态。 一旦渲染完成,新内容就会自动替换进来。 loading UI

即时加载状态

即时加载状态是在导航后立即显示的回退 UI。 您可以预渲染加载指示器,如骨架屏和旋转器,或者未来屏幕的一个小但有意义的部分,例如封面照片、标题等。 这有助于用户了解应用正在响应并提供更好的用户体验。

通过在文件夹内添加 loading.js 文件来创建加载状态。 loading special file

app/dashboard/loading.tsx

import LoadingSkeleton from './LoadingSkeleton';

export default function Loading() {
// 可以在 Loading 中添加任何 UI,包括骨架屏。
return <LoadingSkeleton />;
}

在同一文件夹中,loading.js 将嵌套在 layout.js 内。 它将自动将 page.js 文件和下面的任何子元素包装在 <Suspense> 边界内。 loading overview

值得知道:

  • 导航是立即的,即使是在以服务器为中心的路由中。
  • 导航是可中断的,这意味着在完全加载路由内容之前,不需要等待更改路由以导航到另一个路由。
  • 共享布局在加载新路由段时仍然可交互。
提示

在 Next.js 中,建议使用 loading.js 约定为路由段(布局和页面),因为 Next.js 优化了这一功能。

使用 Suspense 进行流式处理

除了 loading.js 外,您还可以为自己的 UI 组件手动创建 Suspense 边界。 App Router 支持在 Node.js 和 Edge 运行时 使用 Suspense 进行流式处理。

什么是流式处理?

要了解 React 和 Next.js 中流式处理的工作原理,理解**服务器端渲染(SSR)**及其局限性是有帮助的。

使用 SSR,需要完成一系列步骤,用户才能看到并与页面交互:

  1. 首先,在服务器上获取给定页面的所有数据。
  2. 然后,服务器渲染页面的 HTML。
  3. 将页面的 HTML、CSS 和 JavaScript 发送到客户端。
  4. 使用生成的 HTML 和 CSS 显示一个非交互式用户界面。
  5. 最后,React 对用户界面进行水合。

server rendering without streaming chart

这些步骤是顺序和阻塞的,这意味着服务器只能在获取所有数据之后才能渲染页面的 HTML。 并且在客户端,React 只能在下载页面中所有组件的代码之后才能进行水合。

结合 React 和 Next.js 的 SSR 通过尽快向用户显示非交互式页面来帮助提高感知加载性能。 server rendering without streaming

流式处理允许您将页面的 HTML 拆分为较小的块,并逐渐将这些块从服务器发送到客户端。

server rendering with streaming

这使页面的某些部分可以更早地显示,而无需等待所有数据加载完毕才能渲染任何 UI。

流式处理与 React 的组件模型配合得很好,因为可以将每个组件视为一个块。 具有较高优先级(例如产品信息)或不依赖于数据的组件(例如布局)可以首先发送,React 可以更早地开始水合。 具有较低优先级(例如评论、相关产品)的组件可以在数据获取后在同一服务器请求中发送。 server rendering with streaming chart

当你想防止长时间的数据请求阻塞页面渲染时,流媒体尤其有用, 因为它可以缩短时间优先于字节(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,您可以获得以下好处:

  • 流式服务器渲染 - 逐步将 HTML 从服务器渲染到客户端。
  • 选择性水合 - React 根据用户交互优先考虑哪些组件首先进行交互。

有关更多 Suspense 示例和用例,请参阅 React 文档

SEO

Next.js 将等待 generateMetadata 中的数据获取完成, 然后再将 UI 流式处理到客户端。 这确保了流式响应的第一部分包含 <head> 标签。

由于流式处理是服务器渲染的,它不会影响 SEO。 您可以使用 Google 的 Mobile Friendly Test 工具查看页面对 Google 网络爬虫的外观, 并查看序列化的 HTML(源代码)。

状态码

在流式处理时,将返回 200 状态码,以表示请求成功。

服务器仍然可以通过流式内容本身向客户端通报错误或问题,例如在使用redirectnotFound 时。 由于响应头已经发送到客户端,响应的状态码无法更新。这不会影响 SEO。