# C/S Rendering

# 发展历程

# 完全 CSR

最早,网页只有简单的信息展示,没有服务端,只有服务器返回静态资源。这是完全的 Client Side Rendering。

以下是完全 CSR 的流程,其中 C 代表客户端:

  • C 请求页面
  • 服务器返回 HTML 文件
  • C 解析 HTML 文件为 DOM,请求 CSS
  • 服务器返回 CSS 文件
  • C 渲染 DOM + CSS

# 完全 SSR

随着网页功能的增长,需要对不同的用户显示不同的内容。于是,模板引擎出现,服务端获取不同的数据后填入模板引擎,最后将填充完毕的 HTML 返回。这是完全的 Server Side Rendering。

以下是完全 SSR 的流程,其中 S 代表服务端,D 代表数据库:

  • C 请求页面
  • S 从 D 读取数据,处理数据,填充模板引擎
  • S 返回填充完毕的 HTML 文件
  • C 解析 HTML 文件为 DOM,请求 CSS
  • 服务器返回 CSS 文件
  • C 渲染 DOM + CSS

在完全 CSR 和 完全 SSR 中,JS 基本都不参与渲染,只负责处理点击等一些小事,所以在流程中直接略去。

虽然满足了网页功能的需求,但 SSR 还存在这样一些问题:

  • 性能较差:每次请求都要重复执行一遍数据逻辑和视图逻辑生成 HTML,即使其中大部分内容都是相同的
    • 也有说法是刷新页面会带来不好的用户体验
  • 成本较高:Tomcat 等应用服务器相比 Nginx 等 Web 服务器,处理并发的能力较差,因此需要部署更多机器
  • 开发混乱:网页开发和后端开发的职责在视图层高度耦合,开发人员难以协作

# CSR

随着客户端能力的提升,我们提出了一个新的思路——前后端分离:视图层的职责完全划分到前端,后端只负责提供数据,而前端负责用 ajax 请求数据,用 JS 修改 DOM 填充数据。这样的方案解决了 SSR 的问题:

  • 无需重新请求(刷新)即可更新视图
  • 减轻了服务端的负担,利用了客户端的硬件资源
  • 前后端职责分明,协作简单

这就是我们现在印象中的 CSR,以下是它的流程:

  • C 请求页面
  • 服务器返回 HTML 文件
  • C 解析 HTML 文件为 DOM,请求 CSS 和 JS
  • 服务器返回 CSS 和 JS 文件
  • C 渲染 DOM + CSS
  • C 执行 JS,请求数据接口
  • S 返回数据
  • C 执行 JS 将数据填入 DOM,重新渲染

前端拥有了自己的领地后,大刀阔斧地进行改革,时至今日,组件化的 SPA(Single Page Applicaton,单页应用)已经成为大多数前端应用的模式,它比上面所说的 CSR 更加极限:

  • 路由完全由客户端控制,服务器只返回一个 index.html,所有页面全部由客户端动态渲染

然而,随着前端复杂度的不断攀升,CSR 也暴露出了一些问题:

  • 逻辑过多或数据过多时,客户端渲染速度过慢,影响用户体验(首屏加载问题)
  • 网页本质上是一个空的 index.html,不利于 SEO(Search Engine Optimization)

# SSR

为了解决客户端性能不足的问题,服务端又一次登上舞台。服务端性能可控,且获取内网的数据更快,基本上能够解决 CSR 的问题。然而,SSR 在大致流程上与完全 SSR 并没有区别,所以同样要面临之前提到的三个问题,但我们已经或多或少有了一些解决办法:

  • 对重复请求的内容采取缓存策略
    • SSG(Static Site Generation),在编译时生成静态资源 HTML,可部署至 CDN 避免实时渲染
  • 服务器成本可以通过云服务削减
  • 现在的 SSR 框架大多基于 Node.js,与前端同构,一份代码既可以在客户端又可以在服务端渲染
    • 所以 SSR 本质上是前端抢了服务器资源来做渲染,并没有抢后端的活儿

# 未来方向

本篇文章的由来就是发现了 Facebook(或许应该叫它 Meta 了)的新理念——React Server Component,引起了我对 Client or Server Rendering 的一些思考和求证,它会是未来的全新方向吗?我们下篇再议。

# 参考

jsp页面post传值 (opens new window)

如何看待 React Server Component (opens new window)

服务端渲染SSR(Server Side Rendering) (opens new window)

Last Updated: 11/2/2021, 8:56:48 PM