跳到内容

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" 指令用作客户端组件。

参考

参数

加载 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.js 将嵌套在 layout.js 内部。它将自动将 page.js 文件及其下方的任何子级包装在 <Suspense> 边界中。

loading.js overview

SEO

  • 对于只抓取静态 HTML 且无法像完整浏览器那样执行 JavaScript 的爬虫(例如 Twitterbot),Next.js 会在流式 UI 之前解析 generateMetadata,并将元数据放在初始 HTML 的 <head> 中。
  • 否则,可以使用流式元数据。Next.js 会自动检测用户代理以选择阻塞和流式行为。
  • 由于流式传输是服务器端渲染的,因此它不会影响 SEO。你可以使用 Google 的 富媒体搜索结果测试 工具,查看你的页面在 Google 网页抓取工具中的显示方式,并查看序列化的 HTML(来源)。

状态码

当进行流式传输时,将返回 200 状态码,表示请求成功。

服务器仍然可以在流式传输的内容本身向客户端传达错误或问题,例如在使用 redirectnotFound 时。由于响应头已经发送到客户端,因此无法更新响应的状态码。

例如,当 404 页面流式传输到客户端时,Next.js 会在流式传输的 HTML 中包含一个 <meta name="robots" content="noindex"> 标签。这会阻止搜索引擎索引该 URL,即使 HTTP 状态为 200。请参阅 Google 关于 robots 元标签 的指南。

一些爬虫可能会将这些响应标记为“软 404”。在流式传输的情况下,这不会导致索引,因为页面在 HTML 中明确标记为 noindex

如果出于合规性或分析目的需要 404 状态,请确保在响应正文流式传输之前资源存在,以便服务器可以设置 HTTP 状态码。

你可以在 proxy 中运行此检查,将缺失的 slug 重写为未找到的路由,或者生成 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 已引入。