2024了,回看服务端渲染(SSR) VS 客户端渲染 (CSR)


服务端渲染(SSR) VS 客户端渲染 (CSR)

背景

没想到,到了2024年,服务端渲染这个词又火🔥🔥起来了。 之所以添加上了一个“又”字,是因为在前端刀耕火种的时代,服务端渲染应该是默认选项。彼时,还没有客户端渲染(CSR)。

那么,接下来就再一起回顾下 SSR 和 CSR。

什么是服务端渲染

服务器端渲染是一种在服务器端而不是在用户浏览器中生成 HTML 的技术。当用户请求一个网页时,服务器会处理该请求并返回一个完全生成好的 HTML 页面。在现代前端开发模式出现之前,当时的网络页面大部分都算作服务端渲染。

当时的开发模式是,后端同学主要处理数据逻辑,对于页面展示部分的工作,则交给前端同学(更糟的时候甚至没有前端这个岗位)去处理,然后前后端的代码合并在同一个文件(一般情况下)之中。这种模式下,浏览器接收到的数据一般就是完整的 HTML 源码。会包含少量的 JS 代码,主要用于处理简单的交互逻辑和动画效果。

后续,随着 Angular 和 React 的问世,配合 AMD、Sea.js 等各种模块定义规范的普及。前端在页面渲染效率和 JS 文件的加载能力上,得到了跨层级的提升。越来越多的交互逻辑交给了前端负责,服务端只负责数据的获取,前后端分离的这种模式,给予了双方极大的自由度和灵活性,非常利于业务的快速迭代。

什么又是客户端渲染

客户端渲染的初始页面是一个空白的 HTML 外壳以及该页面所需的 JavaScript,然后 JavaScript 用于更新 DOM 并渲染页面。现代单页面应用都属于 CSR 的范畴,都是先下载html文档(不是最终的完全的html),然后下载js来执行渲染出页面结果。 服务器返回到客户端的数据类似于下面这种:

<!DOCTYPE html>
<html lang="en">
 <head> 
  <title data-react-helmet="true">SPA Site</title> 
 </head>
 <body>
  <noscript>
   You need to enable JavaScript to run this app.
  </noscript> 
  <div id="root"></div>
  <script type="text/javascript" src="/static/js/bundle.js" defer=""></script>
 </body>
</html>

SSR 和 CSR 优缺点对比

SSR 的特点

SSR 的工作流程:

  1. 客户端向服务器发出 HTTP 请求。
  2. 服务器接收到请求后,立即处理**所有(或大部分)**必要的代码。
  3. 最终形成一个完整的、易于使用的 HTML 页面,并发送到客户端浏览器。

使用 SSR 时,服务器为网页生成完整的 HTML,并将其发送给客户端。这意味着用户在首次请求时就会收到一个包含内容、可即时显示的完整 HTML 文档。

SSR 的特点

  1. ✅ 搜索引擎友好:SSR 对搜索引擎高度友好,因为搜索引擎可以有效地抓取和索引内容。内容存在于最初的 HTML response中,因此很容易被搜索引擎机器人发现。
  2. ✅ 首屏等待: SSR 可提供卓越的感知性能。用户可以体验到更快的内容加载速度,因为初始 HTML 已发送到客户端,从而缩短了内容显示在屏幕上所需的时间。这对使用较慢连接或设备的用户尤其有利。
  3. ❌ 复杂性: 实施 SSR 可能会更复杂,因为它涉及服务器端渲染框架,并可能需要更多的服务器端代码。不过,好处往往大于增加的复杂性。
  4. ❌ 服务器负载:SSR 可能会增加服务器的负载,因为它必须为每个请求生成 HTML。所以,可扩展性和服务器资源成为重要的考虑因素。
  5. ❌ 动态更新:页面内容需要更新时,会对整个页面的内容进行reload,耗时较长,用户体验不好。

CSR 的特点

CSR 的工作流程:

  1. 客户端向服务器发出 HTTP 请求。
  2. 服务器接收到请求后,会向客户端发送一个空的 HTML 外壳和一堆捆绑的 JavaScript。
  3. 客户端收到空的 HTML 外壳后,开始处理所有 JavaScript。
  4. JavaScript 对 DOM 进行了大量修改,从而为最终用户渲染出最终的 HTML。

在 CSR 中,服务器会发送一个最小的 HTML 文档和 JavaScript 文件。初始 HTML 通常包含内容占位符。其实际内容由 JavaScript 在客户端加载和呈现。

CSR 的特点

  1. ❌ 搜索引擎优化挑战: CSR 的主要挑战之一是搜索引擎优化。搜索引擎可能难以抓取通过 JavaScript 动态加载的内容。这个问题可以通过对特定页面进行服务端渲染来缓解。
  2. ❌ 首屏等待:所有的数据请求和 Dom 渲染都在浏览器端完成,因此当第一次访问页面的时候,可能会出现等待时间。
  3. ✅ 开发简单: CSR 的开发比较简单,因为大部分呈现逻辑都是在客户端使用 React、Angular 或 Vue.js 等 JavaScript 框架处理的。这使其成为许多现代网络应用程序的一个极具吸引力的选择。
  4. ✅ 服务器负载: CSR 可以减少服务器负载,因为服务器主要提供静态资产,不需要为每个请求生成 HTML,这可以节约成本并提高可扩展性。
  5. ✅ 动态更新: CSR 在实现动态更新方面表现出色,无需重新加载整个页面。它非常适合单页面应用程序 (SPA),在这种情况下,内容可以频繁更改,而无需完全刷新页面。

二者优点的结合体 —— 同构渲染

从上文可以看出,SSR 和 CSR 在优缺点上,正好相反,那能不能只取二者的优点,而舍弃掉缺点呢?

也就是说,服务器在首次加载时渲染并发回完全渲染好的 HTML 数据。 然后由浏览器端执行 JavaScript 程序,进行附加事件处理程序,并像客户端路由器一样连接起来。

通过这种方式,可以在首次加载时获得 SSR 的所有优势,然后从那时起的每次交互都将由客户端的 JavaScript 处理。这样就能实现快速、搜索引擎友好的初始加载,然后是我们所熟知和喜爱的动态单页面网络应用体验。

这样的渲染模式被称为“同构渲染”,因为客户端和服务器上运行的是相同的 JavaScript。

结论

选择 SSR 还是 CSR 取决于项目的具体要求和目标。SSR 非常适合内容多交互少的网站,在这些网站中,搜索引擎优化至关重要,初始加载性能也很重要。另一方面,CSR 是动态交互式网络应用程序的理想选择。在这种情况下,内容会经常变化,而无需重新加载整个页面。许多现代网络应用程序同时使用这两种方法,即所谓的同构渲染,以便在适当的时候利用每种方法的优势。

虽然同构渲染结合了 SSR 和 CSR 二者的优点,但是这种开发模式带来的复杂性也应该是开发中应当考量的因素。

只选择对的,不选择贵的。