React:我们即将和后端 API 告别?( 二 )

  • ……(实在太多了)
  • 每一个接口,单独拿出来看都是合理的,但是放在一起,就会发现用户每次打开这样一个音乐 web App,都要发送至少十几个接口,对于一些稍微复杂一点的网页,首次加载就需要请求几十个接口也丝毫不奇怪 。
    每一个接口的请求,都会带来网络开销,甚至在有些环境下会有最大并发请求数量的限制(例如在支付宝客户端那的 rpc 请求),或许网络层的 automatic batching 可以解决这个问题,但是遗憾的是,在目前的技术体系内,这个问题并不好解决(这里没有写不能解决,是因为的确有一些可行的方案,例如 BFF、依赖网关来做接口聚合,但它们都引入的新的问题) 。
    前端包体积(Bundle size)包体积已经是“现代”前端开发领域饱受诟病的一点了,动辄几百 k 的 js 文件,似乎已经背离了浏览器是用来“浏览”网页的初衷了 。并不是说我们都要做一个浏览器原教旨主义者,但是如果网页能够在不损失用户体验和开发体验的前提下,恢复到非常轻量和快速的状态,难道不是一件好事么?
    协作成本(沟通、逻辑感知和封闭)在我个人看来,这是大型项目或需要长期维护的应用中最令人头疼的问题了 。
    假设我们现在有一个非常巨大的应用,需要有十几位开发者共同编写和维护,那如何分工?答案必然是先做模块化,我们把整个应用拆分成几个彼此尽量独立的模块,再由每个人或每几个人负责其中的一个模块 。
    模块化带来的好处是边界清晰(看到一个需求就能判断出来涉及到哪个或哪些模块做哪些改动)、职责明确(每个人都有自己确定的职责)、减少沟通成本(由于模块内部的逻辑是封闭的,不需要外部感知,所以可以降低沟通成本) 。
    对于前两点,目前的前后端分离架构都还是及格的,但对于第三点,我觉得基于网络请求接口的协作模式,在很多情况下并没有有效地做到逻辑内部封闭、减少需要前后端之间来回沟通的信息量 。
    举个例子,对于这样的一个页面:
    React:我们即将和后端 API 告别?

    文章插图
     
    看起来非常简单,一些信息的展示,加上一个充值按钮,这就是我最开始所设想的 。
    然而,随着这个项目不断的推进,我发现,原本以为是纯静态的标题文案,实际上是需要后端控制的,根据当前用户的所属人群来动态判断文案内容;我发现,由于前端金额计算的可靠性问题,折扣和实际支付相关的内容都是需要在后端预处理之后展示在前端的;
    我发现,倒计时的参考时间是需要依靠后端返回的;我发现,按钮的文案、点击行为,是需要后端控制的,特别是按钮的点击行为,最终方案是后端返回一个枚举,前端根据这个值来 switch case 一下走不同的逻辑(例如下单、引导先进行注册和绑卡)……
    为了阅读体验,我只是列举了其中随手想到的一小部分,如果总结一下,那就是,后端和前端并没有因为“前后端分离”而做到解藕,反倒是藕断丝连,剪不断理还乱 。后端感知了过多的前端视图层逻辑,就像是发明了一套 DSL(Domain Specific Language),而前端则是要写一个针对这套 DSL 的解析器和渲染器 。
    回到我们刚刚提到的,模块化带来的好处 。模块化能够降低沟通成本,有一个不可忽略前提,就是架构的合理性 。模块化并非是降低沟通成本的本质原因,也并非所有的模块化实践都能带来沟通成本的降低 。当前后端分离的实践成为一个僵硬的、死板的“规范”,那它还能真正起到多少降低沟通成本的作用?一个大大的问号 。
    Server Components再次申明一下,下文是假设读者朋友已经对 Server Components [3] 有所了解
    基于网络请求的 API 模型,有一个大大的前提假设,就是前端应用和后端应用是两个独立的应用,但是为什么一定要是这样?
    或许我们可以让后端应用直接渲染 html,用户操作时,重新渲染一遍页面?这其实就是在 Restful 时代之前的架构,有很多弊端,特别是可交互性差,不然也就不会出现后来 Restful 的盛行了 。
    那再或许,我们可以让前端的 React 组件,运行在后端?
    这就是 React Server Components 。
    一图胜千言,在现在的前后端分离模式下,后端提供接口,前端的 React 组件调用接口 。


    推荐阅读