NextJS v13 的渲染机制有什么不同?

关注 NextJS 的朋友都知道,NextJS 在 v13 版本推出了 app router模式,还支持了 use client 指令,与 app router 模式和 use client 指令息息相关的,是 NextJS v13 对渲染机制的优化。在新的渲染机制下,我们可以更灵活地控制服务端渲染(SSR)和客户端渲染(CSR),实现更高性能的 Web 体验。

混合渲染

在早期版本中,NextJS 主要采用服务端渲染的方式。而在 v13 版本中,NextJS 实现了同时支持服务端渲染和客户端渲染。开发者可以在同一个应用中采用两种渲染方式的组合。当服务端渲染的组件内容和客户端渲染的组件内容合并生成用户界面时,这就实现了混合渲染。

那么,为什么 NextJS 这次要区分服务端渲染和客户端渲染呢?我们先来看一张图

next渲染机制1.png

这是我们印象中的客户端和服务端:

  • 客户端是在浏览器展示界面
  • 服务端在服务区上存储代码、计算数据
  • 客户端和服务端可以通过请求交换信息

也就是说,客户端和服务端它们功能迥异、使命不同。

那么,如果能扬长避短,最大程度发挥客户端和服务端的优势,是不是就可以让我们开发的产品获得更好的性能?正是基于这样的理念,NextJS才有了服务端渲染和客户端渲染并存的设计。

总结来说,从 v13 版开始,NextJS 希望开发者对应用进行更细致地划分渲染环境,以实现更高性能的产品。而框架为此做的工作就是混合服务端和客户端的渲染结果,展示到用户面前。

网络边界

我们知道,服务端和客户端是通过网络进行交互的,先来看一下网络请求的生命周期:

  1. 用户交互:用户通过点击、输入等方式与应用交互。
  2. 发起HTTP请求:客户端向服务器发起HTTP请求,包含所需资源、方法等信息。
  3. 服务器处理:服务器接收请求,进行诸如路由、数据获取等处理。
  4. 返回HTTP响应:服务器向客户端发送HTTP响应,包含状态码和请求资源。
  5. 客户端渲染:客户端解析响应资源,渲染用户界面。
  6. 用户交互:用户继续与渲染后的界面交互,周期重新开始。

根据请求-响应生命周期不同阶段,服务端渲染和客户端渲染各自的擅长和限制如下:

服务端渲染的优势和适用场景:

  • 请求处理阶段:可以进行数据获取,读取数据库
  • 生成响应阶段:可以渲染HTML页面
  • 有利于SEO,爬虫可以获取预渲染内容
  • 可以快速构建首屏阶段需要的页面内容

客户端渲染的优势和适用场景:

  • 获取响应后可以与用户交互,绑定事件
  • 可以进行复杂的客户端路由和状态管理
  • 可异步加载额外的数据和资源
  • 渲染交互复杂的组件或功能
  • 提供更流畅的用户体验

要划分渲染环境,等同于划分网络边界,那么在NextJS里用什么来划分网络边界呢?

就是使用“use client”。

next渲染机制2.png

NextJS 的页面和组件默认是服务端渲染,只有使用了 use client 指令的页面或组件,它和它的子组件都将是客户端渲染。use client 更详细的用法推荐模式将在下一篇详细解读,现在只要记住它的作用就可以。

那么 NextJS 推荐开发者划分网络边界的原因是什么呢?总结下来有这几点:

  1. 分离关注点:网络边界的不同侧关注不同的功能,客户端关注用户界面,服务器端关注数据获取和处理。明确分离有利于模块化开发。
  2. 利用不同环境的优势:客户端和服务器端有各自的优势,例如客户端可以快速交互,服务器端可以访问数据库。划分边界可以发挥两者优势。
  3. 优化性能:适当地划分边界可以优化应用加载速度、响应速度等性能。比如服务器渲染可以加快首屏加载。
  4. 调整部署位置:边界可以让部分代码运行在客户机,部分在服务器。这为代码部署提供灵活性。
  5. 安全:对边界两侧的代码施加不同限制,可以提高应用安全性。
  6. 离线使用:客户端代码可以在断网时继续工作,提高应用可靠性。

结语

学完以上的概念,我们就对 Next v13 版本的混合渲染有了初步的了解,猛烈点击开始学习NextJS v13服务端组件和客户端组件及最佳实践

专栏资源

专栏介绍:以实战的角度进行Next.js生态圈的技术栈分享,内容包括但不限于:Next.js理论知识、功能模块设计思路、实战中使用到的技术栈。这是一个长期更新的专栏,我会持续把自己的思考和经验提炼分享出来,欢迎关注我的专栏👇

专栏地址:👉Next.js生态圈实战

专栏演示站:👉Next.js Demos

专栏源码仓库:👉Github - Source Code

交个朋友:👉加入「独立全栈交流群」