NextJS

自从 NextJS 正式引入了 React Server Component(以下简称 RSC)功能以后,它现在提供了两种不同的架构模式:传统的页面路由(结合服务器端渲染 SSR 和客户端渲染 CSR 的客户端组件)和新推出的应用路由(结合 SSR、CSR 以及 RSC 的客户端组件)。因此,在开始使用 NextJS 开发项目之前,首先需要考虑你的项目是否真的需要利用服务器端组件。

这可能会让人感到有些迷惑。按照常理,服务器端渲染(SSR)不就是指在服务器上渲染组件吗?那为何还要引入一个名为 React Server Component(RSC)的概念呢?

这里有一个重要的区别需要明确:RSC 并不是一种新的渲染技术。也就是说,在应用路由架构下,渲染的机制与之前的架构相同,都是通过结合服务器端渲染(SSR)与客户端渲染(CSR)来实现的。在服务器端进行的渲染被称为 SSR,在浏览器端进行的水合及随后的渲染过程则是 CSR,这与原有的架构保持一致。

在这个新架构中,无论在什么情况下,RSC 组件都仅在服务器端进行渲染,包括页面跳转时。也就是说,RSC 组件始终采用 SSR 方式渲染。而其他类型的组件(我们可以称之为通用组件)在页面初次加载时会通过 SSR 渲染,随后转为 CSR 进行渲染。这意味着,在水合后,这些通用组件只会在浏览器端进行渲染。

上面的话描述的非常拗口。或许需要一个图解来帮助理解。

  • 传统的 Page Router 中组件的渲染方式:

*:我们定义两个页面,A 页面中存在 组件 A,B 页面中存在 组件 B。

Excalidraw Loading...

可以看到原先架构中,Component A 在初次渲染时由 SSR 结构决定,而在水合之后完全由浏览器测决定。在应用内二跳时,页面 B 中的 组件 B 通过加载的 chunk 完全在浏览器端完成了渲染,不再依赖服务器。

  • App Router 的 RSC 渲染方式:

*:我们定义两个页面,A 页面中存在 通用组件 A,B 页面中存在 RSC 组件 B。

Excalidraw Loading...

与上面不同的是,Component B 作为 RSC,不管在什么情况下都由服务器渲染完成,浏览器只能等待服务器完成渲染之后解析 RSC Payload 才能完成页面的完整渲染。上图中还有一个需要注意的地方,Suspense 包裹了 组件 B,如果没有这个 Suspense,那么整个页面都需要等待 组件 B 渲染完成才能显示,那么在浏览器上的这段时间内这表现为无响应。这是非常影响用户体验的。

**: 后续会讲解 NextJS 提供的 loading.jsx 去解决这一问题。

Note

React Server Component Payload (RSC Payload) 是呈现的 React 服务器组件树的紧凑二进制表示。它由 React 在客户端使用以更新浏览器的 DOM。React 服务器组件负载包含:

  • 服务器组件的呈现结果
  • 客户端组件应该被呈现和对其 JavaScript 文件引用的占位符
  • 从服务器组件传递给客户端组件的任何 props

要了解更多信息,请参阅服务器组件文档

推荐阅读:Understanding React Server Components – Vercel


所以,说是渲染方式,感觉说成是载入方式也许会更加好理解。

选择是十分重要的,因为在两种架构之间迁移需要对大量代码进行重构,如果不在项目初期就决定合适的架构,那么后续发展会变得十分困难。

那么本书主要以 NextJS 新架构 App Router 的视角展开描述,当然也会在其中引申新老架构之间的对比和在业务中的影响。

下一节,聊聊流行的状态管理。


最后更新于 2024/4/27 20:14:01

更新历史

本书还在编写中..

前往 https://innei.in/posts/tech/my-first-nextjs-book-here#comment 发表你的观点吧。