华人澳洲中文论坛

热图推荐

    React:咱们行将和后端 API 辞别搞?

    [复制链接]

    2022-7-31 06:44:26 21 0

    前言
    2020 年底,React 发布了一个全新的特性:Server Components,过后它还处于调研和实验阶段,并无正式公布,跟着 React 18.0 版本的正式公布,Server Component 的脚步声也愈来愈近了,不出不测的话,应该会在往年的某个 React 18 的 minor 版本中正式公布。
    Server Components 听起来好像其实不那末冲动人心,React 18 所公布的各种特性也似乎平平无奇,自从 Hooks 面世曾经三年多过来了,React 似乎停滞了后退的脚步,只是在现有的根底上做些小修小补?
    No。
    Concurrent rendering(React 18 新带来的特性)是一种实质上的改动,它自身不像 Hooks 那样对开发体验有着近乎天翻地覆的改革,然而这类底层渲染才能/机制的调剂,会带来十分十分多的可能性,例如:
    Suspense、OffScreen、Server Components
    这三种特性,目前都没有出产可用,然而比及将来他们正式公布并渐渐被大面积使历时,每一个项特性都会带来十分明显的开发体验的晋升。而假如让我从这些将来会泛起的新特性中选一个最期待的,那绝不疑难会是 Server Component。
    所以,Server Components 究竟是甚么?他会像当年的 Hooks 同样对全部 React 生态带来微小的影响么?在咱们回答这些问题以前,颇有须要先解释一下 Server Components 是甚么,又解决了甚么问题。
    注:下文中的得多内容受 Dan 和 Lauren 的这份 演讲视频 [1] 所启示,假如你想更深化的理解行将到来的 React Server Component,那末十分保举这段视频 事实上,这篇文章并非一份对 Server Components 的用法教学,也不会涵盖 Server Components 的每一个处细节(乃至为了便利表述会无意地略过一些细节),因此, 在读下文以前,最佳是对 Server Components 曾经有所理解
    配景:先后端别离
    “先后端别离”是当下主流的 web 研发模式,后端存储数据,并把对数据的操作(增删改查)封装成接口,经过后端办事提供应前端,前端运用发送申请(例如 http 申请或者 rpc 申请)去调用后端提供的接口,从而获得到数据或者是对数据进行修正。


    这多是十几年以来十分广泛的研发模式了,也因此,咱们被区别成前端开发和后端开发,各自傲责着“楚银河界”的一侧。咱们在各自那一侧都做了十分多的优化、翻新、冲破,在后端,咱们有容器化、微办事、SSR,在前端,咱们有 code spliting、前端路由、React Hooks。
    然而关于 API 层,咱们似乎这么多年以来都不曾有过关注,即使是有,也仅仅是停留于 API 传输机能(例如 grpc)、API 的存在方式(例如 Restful 和 GraphQL)、API 的工程化办理(例如 Postman)。
    并不是是想说 API 一个邪恶而蹩脚的设计,然而自从 Restful 的概念被提出以来,曾经 22 年过来了,咱们是否应该在当初从新思考一下:
    以网络申请作为先后真个分界是最优解吗?假如没有 API,咱们该如何架构和开发 Web 运用?关键所在让咱们再回到刚刚的那张图,斟酌一下 API 在带来职责分工清晰以外,同时也带来了哪些问题。
    申请瀑布流(Waterfall)
    就像 Remix [2] 首页上所展现的,基于 API 和嵌套路由的前端站点,在申请时会泛起瀑布流的景象:
    数据的之间多是有先后的依赖瓜葛,抑或是和组件强耦合在一同,需求等候组件的 bundle 加载实现之后能力收回申请,这些都致使了申请瀑布流景象的泛起。
    并发申请
    后端但愿完成小而美的接口,每个接口有独立的职责,例如:
    getUser 获得用户信息getSongs?page=十二 获得歌曲列表getNotifactions 获得通知列表getFavoirateSongs 获得保藏的歌曲getNewSongs 获得新公布的歌曲getReco妹妹endSong 获得今日保举的歌曲及对应的案牍getSearchBarHotKeywords 获得抢手的搜寻词getAdBanner 获得广告 banner 内容getRecentSongs 获得比来听歌记载getReco妹妹endedPlayList 获得保举的歌单列表……(真实太多了)每一个个接口,独自拿出来看都是公道的,然而放在一同,就会发现用户每次关上这样一个音乐 web app,都要发送最少十几个接口,关于一些略微繁杂一点的网页,初次加载就需求申请几十个接口也涓滴不奇怪。
    每一个个接口的申请,都会带来网络开消,乃至在有些环境下会有最大并发申请数量的限度(例如在领取宝客户端那的 rpc 申请),也许网络层的 automatic batching 能够解决这个问题,然而遗憾的是,在目前的技术体系内,这个问题其实不好解决(这里没有写不克不及解决,是由于确实有一些可行的计划,例如 BFF、依赖网关来做接口聚合,但它们都引入的新的问题)。
    前端包体积(Bundle size)
    包体积曾经是“古代”前端开发畛域饱受诟病的一点了,动辄几百 k 的 js 文件,似乎曾经背离了阅读器是用来“阅读”网页的初衷了。并非说咱们都要做一个阅读器原教旨主义者,然而假如网页可以在不损失用户体验和开发体验的条件下,恢复到十分轻量和疾速的形态,莫非不是一件坏事么?
    合作本钱(沟通、逻辑感知和关闭)
    在我集体看来,这是大型名目或需求长时间保护的运用中最使人头疼的问题了。
    假定咱们当初有一个十分微小的运用,需求有十几位开发者独特编写和保护,那如何分工?谜底必定是先做模块化,咱们把全部运用拆分红几个彼此尽可能独立的模块,再由每集体或每几集体担任其中的一个模块。
    模块化带来的益处是界限明晰(看到一个需要就可以判别出来波及到哪一个或哪些模块做哪些改变)、职责明白(每集体都有本人肯定的职责)、增加沟通本钱(因为模块外部的逻辑是关闭的,不需求内部感知,所以能够升高沟通本钱)。
    关于前两点,目前的先后端别离架构都仍是及格的,但关于第三点,我感觉基于网络申请接口的合作模式,在得多状况下并无无效地做到逻辑外部关闭、增加需求先后端之间往返沟通的信息量。
    举个例子,关于这样的一个页面:


    看起来十分简略,一些信息的展现,加之一个充值按钮,这就是我最开始所构想的。
    但是,跟着这个名目不停的推动,我发现,本来认为是纯动态的标题案牍,其实是需求后端管制的,按照以后用户的所属人群来静态判别案牍内容;我发现,因为前端金额计算的牢靠性问题,折扣和实际领取相干的内容都是需求在后端预处置之后展现在前真个;
    我发现,倒计时的参考时间是需求依托后端前往的;我发现,按钮的案牍、点击行动,是需求后端管制的,特别是按钮的点击行动,终究计划是后端前往一个枚举,前端按照这个值来 switch case 一下走不同的逻辑(例如下单、疏导先进行注册和绑卡)……
    为了浏览体验,我只是罗列了其中顺手想到的一小部份,假如总结一下,那就是,后端和前端并无由于“先后端别离”而做到解藕,反倒是藕断丝连,剪不停理还乱。后端感知了过量的前端视图层逻辑,就像是创造了一套 DSL(Domain Specific Language),而前端则是要写一个针对这套 DSL 的解析器和渲染器。
    回到咱们刚刚提到的,模块化带来的益处。模块化可以升高沟通本钱,有一个不成疏忽条件,就是架构的公道性。模块化并不是是升高沟通本钱的实质缘故,也并不是一切的模块化理论都能带来沟通本钱的升高。以后后端别离的理论成为一个僵直的、死板的“标准”,那它还能真正起到多少升高沟通本钱的作用?一个大大的问号。
    Server Components
    再次声名一下,下文是假定读者敌人曾经对 Server Components [3] 有所理解
    基于网络申请的 API 模型,有一个大大的条件假定,就是前端运用和后端运用是两个独立的运用,然而为何一定要是这样?
    也许咱们能够让后端运用间接渲染 HTML,用户操作时,从新渲染一遍页面?这其实就是在 Restful 时期以前的架构,有得多弊病,特别是可交互性差,否则也就不会泛起起初 Restful 的流行了。
    那再也许,咱们能够让前真个 React 组件,运转在后端?
    这就是 React Server Components。
    一图胜千言,在当初的先后端别离模式下,后端提供接口,前真个 React 组件调用接口。


    而假如后端能够运转 React 组件,间接渲染 React 节点树到前端,就不需求所谓的 API 的概念了。


    后端运转 React 组件并非甚么陈腐事,咱们在 SSR(Server Side Rending)早就司空见惯了,然而需求特别注明的一点是,在 SSR 中,后端是运转了 React 组件,生成为了一份初始形态的 html,但这份 html 是没有可交互性的,它只是为了让用户能及早看到页面而做的一种改善式的、修修补补同样的优化。
    而 Server Components 所带来的,是咱们能够把同一个名目中,一部份的组件作为 Server Components,另外一部份组件,作为 Client Components,因此咱们能够既享用到后端外部调用带来的便捷、可保护性,又能包管页面的可交互性简直没有任何让步。
    假如你用过 PHP 或 Django,那你确定十分相熟这类模式:后端间接渲染 html 内容,阅读器只担任显示,用户点击按钮,那就从新申请、从新渲染页面,假如页面上需求一些繁杂的静态交互,好比让用户能够把一个列表展开/收起,或者是点击某个按钮之后展现一个模态框,那能够借助于 jQuery 来完成。
    PHP + bootstrap + jQuery,当初,Server Components 就像是这套范式的降级版,能够被称为一种全新的“全栈”开发模式。
    由于是在后端环境下,这些 Server Components 能够使用整个的后端才能,不论是两头件,仍是其余后端微办事的调用,乃至是 db 的拜候(固然能够间接跑 SQL,然而更好的理论是经过一个数据两头层),均可以完成。这样一来,咱们就能间接把数据从源头获得,放到 React 组件的上下文中,那天然就不需求传统意义上的 API 了。
    更精确的说,API 并未隐没,咱们其实也不会和 API 就此说再见,而是让它换了一种方式。有模块化之处,就会有 API,Restful 的 http 网络申请当然是 API,但两头件袒露出来的办法,阅读器提供的 Date 对象,node 提供的文件读取函数,db 提供的 SQL,这些全都是 API。
    在这类新架构下,API 变为了后端里业务运用和下游办事之间的调用,变为了 Server Components 和 Client Components 之间的 props 传递,前者让 API 变得更为洁净、更合乎繁多职责的准则,然后者让 API 变得天然到你简直感知不到。
    所以:
    Server Components 允许咱们再也不根据 前端 - 后端 进行模块的拆分,而是依照 业务运用 - 底层办事 来进行更公道的模块拆分。从而能够实践上升高模块之间的沟通本钱(由于目前尚无方法理论证实)。因为 Server Components 是在后端运转组件,间接经过网络传输给前端进行渲染,因此得多大体积的包(例如 markdown 渲染、html sanitize)都不需求在前端下载和运转,从而很大水平上升高包体积。因为底层 db 或下游办事的调用都是产生在后端外部的,因此即使泛起并发申请,所带来开消也远远小于前端并发调用后真个 Restful API。同理,申请瀑布流的问题也会由于调用开消升高而隐没或加重。想象假如斗胆想象一下的话,将来的研发模式可能这样的:
    开发者将不会再区别前端和后端,而是区别为业务运用开发和下游办事开发。当初的后端开发将(真正地)再也不需求关凝视图逻辑,只聚焦于底层业务逻辑,为前端提供明晰好用、原子化的办事/接口;而当初的前端开发将会拓展到横跨前端和后端(代码运转环境上),担任的是在后端封装好的一个个原子化的底层才能上,构建视图层,而咱们也需求一套全新的框架和根底设施,来适配 Server Components。
    目前,Server Components 尚无正式公布,而即使正式公布之后,也还有长长的工程化落地的路要走,Server Components 减少了得多额定的限度,server、client、shared 的区别也可能会带来一些了解本钱。缓存、机能、server 从新渲染时的增量更新战略、公布时的可灰度性和可回滚性、业务中界限状况的处置,还有得多的问题需求去解决,还有得多的未知尚未被验证。
    参考材料
    [1] 演讲视频: http://www.youtube.com/watch?v=TQQPAU21ZUw
    [2] Remix: http://remix.run
    [3] Server Components: http://reactjs.org/blog/2020/十二/21/data-fetching-with-react-server-components.html

    发表回复

    您需要登录后才可以回帖 登录 | 立即注册

    返回列表 本版积分规则

    :
    注册会员
    :
    论坛短信
    :
    未填写
    :
    未填写
    :
    未填写

    主题31

    帖子39

    积分191

    图文推荐