在查看vite的官方文档的时候,看到了一个“后端集成”的条目。这时我被前后端分离架构先入为主的思维陷入了卡顿。
既然vue就是为了支持前后端分离而生,怎么又反向集成了?

之后我查阅了一些资料,发现原来web发展早期,基本都是只有一个后端完成全部的web服务,可能有一些传统(陈旧)的老web应用或者小小项目,仍然需要前后端集成。

简述

在Web发展的早期,确实更多地采用了前后端集成的服务模式,这种模式被称为服务器端渲染(Server-Side Rendering,SSR)。在这种模式下,服务器负责处理业务逻辑、数据存储和页面渲染,然后将完整的HTML页面发送给客户端浏览器进行显示。这样的架构简单而直观,但也存在一些问题,例如页面加载速度较慢、用户体验较差等。

随着Web应用变得更加复杂和交互式,前端和后端分离的架构逐渐变得流行。这种架构被称为前后端分离(Frontend-Backend Separation)或客户端渲染(Client-Side Rendering,CSR)。在前后端分离的模式下,前端负责处理用户界面和交互逻辑,而后端提供API(Application Programming Interface)来处理数据和业务逻辑。前端通过API与后端进行通信,获取所需的数据,并在客户端动态地渲染页面。

这种分离的架构可以提供更好的用户体验、更快的页面加载速度以及更容易实现跨平台开发。现代的Web开发框架和工具,如React、Angular、Vue.js等,都支持前后端分离的开发方式。

前后端分离的概念是随着互联网应用的发展和技术进步逐渐形成的,以适应更复杂、交互性更强的现代 Web 应用的需求。

为此,我查阅了SSR和CSR以及预渲染的概念:

· 服务器端呈现 (SSR):将客户端或通用应用呈现为服务器上的 HTML。
· 客户端渲染 (CSR):通过 JavaScript 在浏览器中渲染应用,以修改 DOM。
· 预渲染:在构建时运行客户端应用,以静态 HTML 的形式捕获其初始状态。

以及性能指标概念:

·Time to First Byte (TTFB):视为从用户点击链接到获取第一项内容之间的间隔时间。
·First Contentful Paint (FCP):请求内容(报道正文等)可见的时间。
·Interaction to Next Paint (INP):被视为代表性指标,用于评估网页是否能够始终如一地快速响应用户输入。
·总阻塞时间 (TBT):INP 的代理指标,用于计算主线程在网页加载期间被阻塞的时间。

SSR

在互联网发展的早期,典型的网页应用是由后端负责处理所有的业务逻辑、数据处理、页面渲染等任务。这种架构被称为传统的多页应用(Multi-Page Application,MPA)架构。

在 MPA 中,用户在浏览器中输入一个 URL 或点击链接时,整个页面会被服务器重新加载,服务器负责生成 HTML、处理请求、渲染页面,并将整个 HTML 页面返回给浏览器。用户的交互主要是通过页面的刷新来实现。

服务器端呈现为服务器上的网页生成完整的 HTML 来响应导航。这可避免在客户端上进行额外的数据提取和模板化操作,因为系统会在浏览器收到响应之前对其进行处理。

与 CSR 相比,其 FCP、TTI 通常会更快,但在服务器上生成页面同样需要时间,会导致页面内容响应时间TTFB(Time to First Byte)变慢

在前端操作较为复杂时,无法完成异步操作!用户必须等待服务器的返回后才能继续操作

服务器端渲染通常会生成快速 FCP。在服务器上运行网页逻辑和呈现可以避免向客户端发送大量 JavaScript。这有助于减少页面的 TBT,这也可能会导致 INP 偏低,因为主线程在网页加载期间不会那么频繁地阻塞。如果主线程的阻塞频率较低,用户互动就会有更多机会更快地运行。这是合理的,因为使用服务器端呈现时,您实际上只是向用户浏览器发送文本和链接。这种方法适用于各种设备和网络条件,并有助于进行一些有趣的浏览器优化,例如流式文档解析。
ssr.png

CSR

随着前端技术的发展和互联网应用的复杂性增加,人们开始意识到在大型应用中,将前端和后端进行分离有一些优势。这种架构被称为前后端分离(Frontend-Backend Separation)或单页应用(Single Page Application,SPA)架构。

在前后端分离的架构中,前端负责处理页面的渲染、用户交互、路由控制等任务,而后端则专注于处理数据、业务逻辑、安全性等方面。这种方式带来了更好的用户体验,减轻了服务器的负担,并允许前后端团队使用不同的技术栈。

可以完成异步操作。在前后端分离的架构中,前端可以通过异步请求(比如使用JavaScript的fetch、axios等工具)向后端发起请求,而不必等待后端的响应。这允许前端在等待数据返回的同时继续执行其他任务,提高了用户体验

主要缺陷在于随着应用程序的更新迭代,客户端所要执行 JS 代码量越来越多

客户端呈现是指使用 JavaScript 直接在浏览器中呈现网页。所有的逻辑、数据提取、模板设置和路由都是在客户端(而不是服务器上)处理的。其有效结果是,更多数据从服务器传递到用户设备,而这也存在一系列权衡取舍。

CSR.png

静态渲染

将生成 HTML 页面的工作放到编译时,而不必在请求带来时动态完成。为每个 URL 预先单独生成 HTML 文件,并进一步借助CDN加速访问

静态呈现的缺点之一是,必须为每个可能的网址生成单独的 HTML 文件。如果您无法提前预测这些网址的具体内容,或者对于包含大量独特网页的网站来说,可能无法实现。

静态渲染在构建时进行。此方法可提供快速 FCP,以及更低的 TBT 和 INP(假设客户端 JS 的数量有限)。与服务器端呈现不同,由于无需在服务器上动态生成网页的 HTML,该呈现方式还可以确保始终快速的 TTFB。一般而言,静态呈现是指为每个网址提前生成单独的 HTML 文件。借助预先生成的 HTML 响应,可以将静态渲染部署到多个 CDN,以充分利用边缘缓存。

static.png

预渲染(Prerendering)

主要区别在于,静态渲染得到的页面已经是可交互的,无需在客户端额外执行大量 JS 代码,而预渲染必须经客户端渲染才真正可交互。也就是说,禁用 JS 后,静态渲染的页面几乎不受影响,而预渲染的页面将只剩下超链接之类的基本功能

总结

通过举例说明作为结束

ChatGPT的交互是通过API实现的。当在页面中输入问题时,实际上是通过网络请求将输入发送到ChatGPT的API,然后等待API的响应。

这种方式是前后端分离,其中前端(在这里是页面)主要负责用户交互和显示,而后端(在这里是ChatGPT的API)负责处理业务逻辑(生成回答)和数据处理。


部署了一个unity的web游戏在网页上。在这种情况下,可以说这是一种前端集成的模型。Unity游戏在浏览器中运行时,它可以独立于后端,直接与用户的浏览器交互。游戏的逻辑和资源通常都包含在游戏的构建文件中,不需要通过网络请求向后端获取。


如果Unity游戏需要与服务器进行数据交互,例如保存游戏状态、获取用户信息、进行多人游戏等,需要使用前后端分离:
在后端设置一个服务器,该服务器负责处理与游戏相关的业务逻辑,例如处理用户请求、保存和检索游戏数据等。
然后定义一组API,用于在前端和后端之间进行通信。Unity游戏可以通过发送HTTP请求(例如使用Unity的WebRequest类)来与这些API进行交互,以获取或发送数据。

参考:

前端渲染模式的探索
在网页上呈现