Next.js的渲染策略
# 服务端组件
服务端组件是可以运行在服务端的React组件。
# 使用服务端组件的优点
- 数据请求。相比传统的客户端发送,服务端处理的方式,服务端组件可以直接在服务端请求数据,减少因为数据请求而导致的页面渲染所需时间。
- 安全性。服务端组件可以将token和一些敏感的数据处理逻辑保留在服务端。
- 减少首屏渲染时间。服务端组件可以直接生成页面HTML代码并发送给客户端,因此页面能够更快速的呈现内容。
- SEO优化。搜索引擎能够抓取到更多有效的关于页面的信息。
- Streaming。服务端组件可以先让页面的一部分展示并具有交互功能,不需要等待整个页面加载完毕。
# 服务端组件渲染流程
服务端组件的渲染流程主要分为5步,分别在客户端和服务端执行。首先是服务端:
- Next.js现将服务端组件转换为一种特殊的数据形式,称为 React Server Component Payload。
- 生成页面的HTML,此时只是静态的页面。
之后RSC Payload和生成的HTML会被发送给客户端:
- 根据HTML,客户端立刻展示给用户一个不具备交互能力的静态页面。
- RSC Payload会协调服务端和客户端的组件树以更新DOM。
- hydrate,执行JS来让页面具有交互能力。
# 服务端组件 VS 服务端渲染
在看到Next.js官方针对服务端组件渲染流程的解释时,很容易让人联想到服务端渲染,它们看起来如此相似。实际上在React团队第一次提出服务端组件的概念之后, 社区里也有很多关于两者之间不同之处的讨论。下面是我个人总结的一些区别:
- 覆盖范围。服务端渲染是将整个页面在服务器上渲染生成HTML,而RSC则是将页面分割成客户端和服务端组件,服务端组件在服务器上渲染。
- 客户端代码量。服务端渲染还是会将整个应用的JS发送至客户端执行,以确保页面具有交互功能。而RSC则可以减少客户端的代码量,因为RSC可以做到仅在必要时才执行客户端代码。
- 用途和目的。服务端渲染的目的是为了加快首屏渲染速度和SEO优化,但是对于服务器的负载较大。RSC的出现则是为了提高服务端和客户端之间的数据交互效率,同时实现对页面渲染更细粒度的控制(可以决定页面哪些部分由服务端渲染,哪些部分由客户端渲染)。
一个不太准确但是比较好理解的说法:服务端组件就是更加精细的服务端渲染,使用服务端渲染的方式来渲染单个组件而非整个页面。
# 客户端组件
Next.js中的React组件默认情况下都是服务端组件。 如果需要使用客户端组件,则需要在组件文件的顶部加入use client
命令告知Next.js该组件是一个客户端组件。
使用服务端组件的好处很多,但是也有其不能覆盖的情况。比如需要使用浏览器的API,或者使用useState
这样的hook的时候,只能使用客户端组件。
# 客户端组件渲染流程
如果是渲染整个页面,使用客户端组件和渲染流程跟上述服务端组件一样。因为虽然是客户端组件,Next.js为了保证首屏快速加载和SEO优化,还是会优先采用渲染服务端组件的策略。
如果只是渲染页面的一部分,比如最常见的前端路由,则此时采用的就是传统的客户端渲染策略。客户端加载并解析JS资源来进行页面渲染。
# 组合渲染策略
服务端组件和客户端组件在同一个项目中经常组件使用。通常对于项目的layout和page都会采用服务端组件,因为它们一般代表了项目的首页,使用服务端组件带来的快速首屏加载能够显著提高用户体验。
而对于需要自己保持状态的组件而言,则需要使用客户端组件。因为类似useState
,useEffect
这样的React Hook只能在客户端组件中使用。
这样有自己状态的组件不需要和服务端进行交互就能对用户的操作进行反馈,对于一个良好的应用而言也是不可缺少的。