本文目录
[[toc]]
思考 RSC 的演变过程
RSC 的演变过程并非一蹴而就,更像是一种自然选择。
RESTful API
在互联网早期,由于页面整体内容较少,基本由后端渲染前端。换句话说,早期前后端交互的方式为: 后端直接将数据注入前端 。
随着电子设备性能的革新、网络传输效率的改进、浏览器运行性能的提升、前端能力的扩展,前端承接着越来越重的工作量。传统的前端先行,后端注入的方式过于浪费时间,所以前端才能独立出来,成为一个单独的岗位。
受 REST 架构的影响,前后端开始分离,来到了 jQuery 时代。
前端通过 Ajax 从后端获取数据,并通过 DOM 操作更新 UI ,此时的路由依旧是后端控制,页面依旧是 MPA 亦或者是后端通过伪静态模拟出来。
这里出现了开发模型的迭代,即: 数据源从后端关注转为前端关注
前端开发的心智模型也出现了对应的调整: 如何实现 UI 效果转变为如何更新 UI
后端从返回 HTML 转为返回 json / xml 数据,但是整体的接口维度还是停留在页面维度。
前端为了能更好的适应新的工作内容,即 如何更新 UI 这一命题 ,诞生了三大框架: Angular 、 React 、 Vue ,前端的心智模型也进一步迭代: 如何关联 state 与 UI
在这一维度下,后端也进行对应的调整,出现了 RESTful API ,即后端不再关注 MVC 中的 View ,转为关注 Model 与 Controller ,为了方便接口复用,出现了 RESTful API ,让后端保持模块独立,与前端页面解耦。
BFF
虽然前后端都进化到比较现代的版本,但是使用的网络通信协议依旧是 90 年代的 HTTP/1.1 ,这使得网络请求非常受限。
由于 RESTful 的最小模块,使得同一个页面可能需要请求多个 RESTful 接口,才能满足页面需要。
然而, HTTP/1.1 在请求时,每个请求都需要创建一个 TCP 连接,如果算上加载静态资源的开销,连接数会非常大,这对操作系统而言是不可接受的,很容易击穿整个 TCP SYN_RECV 队列,导致大量待 ACCEPT 的请求直接被拒绝,形成对操作系统的 DDoS 。
这也使得浏览器不得不限制一个页面对一个源,同时请求不能超过 6 个,避免对操作系统形成较大的负载,其他资源只能排队。
在首次加载时,页面需要发送大量的请求,包括协商缓存有效期、请求新资源、加载数据等,如果说 CDN 可以缓解资源加载的压力,那 RESTful 的特性导致的请求数量膨胀却是难以避免的。
因此,互联网又进一步进化,诞生出 HTTP2 与 BFF 两种解决方案:
- HTTP2 是彻底从网络层重构,使得同一五元组的请求可以复用同一 TCP 连接,而不需要重复握手
- BFF 更像是一个过度方案,主张在 RESTful 与前端中间添加一层 BFF ,将页面使用的数据在服务端完成聚合,统一返回给前端
HTTP2 依赖于浏览器、服务端等的实现,并且对于自签名证书并不友好,部分场景下自签名证书难以开启 HTTP2 请求。
为了向前兼容,大部分企业的方案还是 BFF ,只是这一层 BFF 由谁维护的问题。
在早期确实由后端进行聚合,由于 NodeJS 的兴起,渐渐也出现了前端聚合的方案,尤其是 GraphQL 方案,将 BFF 的维护难度进一步降低。
此时的心智模型,又进一步迭代,前端开始接手部分简单的后端工作,比如 CURD 。
RSC
随着前端内容的迭代,首屏越来越臃肿,需要的 vendors 越来越大,越来越多的企业选择拥抱 SSR / SSG ,事实证明 MPA 还是有其优势的,尤其是在首屏性能方面。
考虑到 GraphQL 本质上是根据一套 DSL ,调用不同的 policy ,获取不同的内容进行返回,实际上对于返回内容并没有进行限制,也就意味着: 接口不一定需要返回接口数据 。
这非常重要,考虑到 SSR 的日渐兴盛,如果将整个组件 destroy ,并从接口直接获取新的 VDOM 或者 HTML ,挂载到原节点位置上,在接口请求不变的情况下,是否意味着这段 VDOM 或者 HTML 也是可以被缓存的。
也就意味着,对于后端数据而言,也是一个较大的缓解压力的方案。
所以, RSC 应运而生了,当然不只是 RSC , Astro 的 island 方案、 Web Component 也是在相同背景下产生或兴盛。