15158846557 在线咨询 在线咨询
15158846557 在线咨询
所在位置: 首页 > 营销资讯 > 网站运营 > 前端搞搭建|沐童-如何设计实现 H5 页面搭建系统 - 数据模型

前端搞搭建|沐童-如何设计实现 H5 页面搭建系统 - 数据模型

时间:2023-09-25 16:54:01 | 来源:网站运营

时间:2023-09-25 16:54:01 来源:网站运营

前端搞搭建|沐童-如何设计实现 H5 页面搭建系统 - 数据模型:

下期预告

6-20,是第十期 - 跨端跨栈 https://www.huodongxing.com/go/tl10

6-27,是第十一期 - 女生专场 https://www.huodongxing.com/go/tl11

另外,每一期都提供了全年的联票,可以看所有场次的录播视频,包括下半年到年底的所有直播视频

前端早早聊大会目标成为用得上、听得懂、抄得走的技术大会,计划 2020 年办 >= 15 期,由前端早早聊与掘金联合举办,前端早早聊大会行程动态、录播视频/PPT/讲稿资料下载请关注 「前端早早聊」 公众号跟进。
你的支持,是早早聊办下去的唯一动力!

还想听哪方面的分享,直接加 Scott 微信: codingdreamer 提需求吧!


正文

本篇为第三届 - 前端页面搭建专场沐童讲师的分享:

1.我是谁?

Hello 大家好,很高兴今天有机会能在这里跟大家分享自己关于页面可视化搭建的一些开发思路。

先简单自我介绍一下,我是沐童,18 年毕业后加入京东,目前就职于京东京喜业务部,也是 WecTeam 的核心成员,在团队里主要负责了内部使用的一个 H5 卖场可视化搭建系统 —— MPM 的建设工作。

2.我们的团队

京东京喜是京东致力于打造下沉电商的战略核心部门,包括京喜小程序(微信购物入口)、京东购物小程序及其他微信手 Q 渠道的业务,都是由我们团队负责维护。在去年,我们自发成立了对外的前端技术团队 WecTeam,希望通过技术分享和项目开源等方式,参与和推动前端技术发展,为行业带来更大价值。

WecTeam 公众号,欢迎关注

二、分享主题

今天想要跟大家分享的主题是《如何设计实现 H5 页面搭建中的数据模型设计》

1.数据模型指的是什么?

2.为什么要讨论数据模型?

3.主题目录

三、MPM 整体介绍

1.系统简介

2.能力概览

3.效果展示

MPM编辑界面




配置发布页面




最终效果图

4.系统架构

5.工作流程

四、数据层面临的痛点

了解完 MPM 的大致情况后,我们再把目光聚焦到 MPM 的数据模型。数据层面临的痛点究竟是什么?为什么 MPM 会对数据模型尤其重视?我们可以从以下几个例子感受到。


1.请求散乱无章




第一种场景:页面请求茫茫多,有时候想定位页面中某个请求来自哪个组件,可能得定位半天。

2.多余的重复请求





第二种场景:某个页面中,有多个组件都配置了同一个预约 ID,导致页面发出了 N 个一模一样的预约态查询请求。

3.接口压力大





第三种场景:商品接口支持批量请求,但由于页面的各个商品组件是独立请求的,导致多个商品请求并没有聚合,走批量调用。

4.数据模型多变





第四种场景:商品组件下的各个模板,除请求商品之外,有些模板会拉取新人价,有些模板会拉取补贴价。

5.三端同构诉求





第五种场景:以 Vue 为例,我们习惯在组件创建时,也就是 created 钩子函数中请求数据,这在客户端渲染时表现很完美,但在直出场景下却完全行不通。

五、数据请求解决方案





基于以上种种问题,我们为自搭建卖场打造了一套高效通用的数据请求解决方案,它包括了以下三个解决目标:

六、页面模型设计





组件楼层配置的结构和内容,它包括:

七、请求模型设计

1.数据源

我们认为,请求模型的复杂性在于请求组合的复杂性,请求可以串联、并联及串并联混合,请求还有主次之分。

要应对请求模型复杂灵活的组合,首先我们需要对请求进行量化,也就是说,我们需要一个最小单元来描述请求,请求模型则基于这些基本单元进行自由组合,这个最小单元就是数据源。



数据源是请求模型的基本组成单位,描述了一类请求动作,它包括以下几个基本属性:





我们用一个类来实现数据源,一旦想要请求这个接口,调用层只需要以配置参数为入参进行实例化,就可以得到一个请求对象,引擎可以理解请求对象,并发起一个真正的请求。

数据源有很多个,每个数据源都有自己的名称标识,在调用层,我们只需要通过数据中心提供的 fetch 方法,指定数据源标识并传入配置数据,就可以建立起和数据源的绑定关系,来选择调用某个数据源。



基于这样的设计,我们可以很方便地实现请求模型的自由组合。

首先我们要求数据源应该是纯粹且专一的,它应该只做一件简单的事,比如跟这个接口密切相关的一些通用处理逻辑,而像一些跟特定部分组件/模板业务逻辑相关的处理,则不应该出现在这里,这是自由组合的前提。

其次,我们允许由数据源以各种形式自由组合成更高级、更复杂的请求模型,或者叫高级数据源。对于调用层来说,既可以直接调用数据源,也可以调用封装好的高级数据模型。



数据源如何组合成高级请求模型呢?这里我们采用了最简单灵活的函数调用,而不再是以类的形式来组织。函数天然拥有的作用域机制,对实现灵活多变的请求模型十分有利。上图就是这样一个例子,我们在函数内串联调用了商品、优惠券两个数据源,简单地实现了一个“带券商品”的请求模型。

高级请求模型是个函数,同样也就拥有唯一的名称标识。所以向上,我们将调用方式对齐,因此对于调用层来说,究竟是直接调用数据源,还是调用高级请求模型,其实没什么区别。



另一方面,依靠数据源,我们也有效地实现了统一管理。上图是数据源请求的整体工作流程,其中有两个核心模块 —— 数据中心和请求中心:



借助这两个核心模块,整个页面请求的流程大致是这样的:

2.请求优化策略

当对页面请求做了统一管理之后,我们就可以对请求做一些合理的优化了。



请求中心的内部机制


2.1 如何避免页面发起重复请求呢?

首先,我们将请求分为了未发起、等待中、已完成三个生命阶段。当请求中心接收请求对象后,会先对请求对象做 MD5 判断:

依靠这样一个简单的请求队列和请求缓存,我们有效避免了页面内发起重复请求。





2.2 如何实现页面内同类接口请求的有效聚合?

前边我们提到,数据源中的 batch 属性可以制定聚合分发策略,上图就是 batch 的内部结构。它包含了三个属性:


每当数据中心创建出一个请求对象的时候,并不会立刻发给请求中心处理,而是先推入一个缓冲队列。等到下一个 Tick 时,数据中心会将上个 Tick 收集到的这一批请求对象,经 pack 函数处理,聚合成一个请求对象,再发给请求中心。等到响应后,再经 unpack 函数拆包,根据拆包映射分发到对应的各个调用层。

当然,假设在当前 Tick 中,缓冲队列内的请求对象达到了规定的上限,那么聚合就会提前执行。



聚合分发的流程

上图可以很明显看出,对于调用层来说,感知上依然是发出了 5 个请求,接收了 5 个响应结果,但对于请求中心来说,只接受并处理了 2 个请求对象,也就是只发出了 2 个请求。所以在这里,聚合分发层其实起到了一个隔离的作用,对于隔离层的两端来说,对方都是黑盒。因此,利用这样一套机制,我们可以很方便地让同类请求合多为一。


3.初态函数

为了实现 MPM 的三端同构,我们设计了初态函数。



可能很多人有疑问:前后端渲染到底有什么区别?假如我把客户端渲染那一套,照搬到直出端,为什么不行?那么这里就跟大家稍微解释下。



在客户端渲染中,我们经常喜欢在 created 钩子函数中编写数据请求,同时以骨架屏或局部 loading 作为占位,等到数据就位后再渲染出有效内容。这是客户端渲染的惯用手段,这也就说明了一个问题:客户端允许存在多趟渲染,大可以边渲染边请求,渲染和请求之间没有严格的先后顺序。


但是在直出端,渲染完成的下一步是向客户端作页面流式输出,有且只有一趟渲染。所以,直出渲染前,用于渲染的数据必须全部到位,也就是说,请求必须在渲染之前完成。

如果你把客户端渲染直接搬到直出端,很遗憾,你可能就只能直出一份骨架屏。



因此,我们可以得出以下几个结论:





基于这些,我们参考现有优秀的前后端同构框架 Next,设计了初态函数。Next 中也有初态函数,只不过 Next 的初态函数只能存在于页面级别,组件中是不允许有初态函数的。而 MPM 是组件搭建场景,我们不可能在页面级别去获取各个组件楼层的数据,因此我们对初态函数做了一些改造。

我们让每个 MPM 组件楼层都拥有一个初态函数,它是位于组件生命周期最开始的一个异步函数。初态函数以组件配置数据为入参,异步返回用于组件初始化渲染需要的初态数据。

三端引擎在创建组件实例之前,会先收集各组件的初态函数,执行,并将函数的异步返回结果作为组件初始化渲染的数据。



基于初态函数,我们对客户端,也就是静态 H5 和小程序端的渲染流程做了一些调整。我们不再允许客户端随意在 created 钩子函数中编写初态数据请求,而是要通过初态函数来实现,为的就是和直出端的页面解析渲染流程保持严格统一,便于同构。



而对于直出端,其解析流程大体和客户端相同,唯一区别是,直出流式渲染后,页面到达客户端需要进行楼层组件的激活,让直出楼层接受 Vue 的状态管理。



有时候我们可能遇到这种场景需求:有一个组件,串联请求了主、次两个接口,次接口内容没那么重要,为了提高直出效率,能不能只直出主接口,次接口等到了客户端再请求呢?



为了实现这类主次接口的分端请求,我们又进一步对初态函数做了一些改造。我们让初态函数支持了这种写法,除了返回一个 Promise 来表示异步之外,我们允许初态函数提供第二个参数 —— callbackcallback 是一个回调函数,用于通知引擎执行渲染,所以我们可以通过在初态函数中多次调用 callback 函数来实现初态数据的分阶段渲染。

对于这类写法的初态函数,直出端只会响应其中的第一个 callback ,也就是说,当第一个 callback 被执行时,直出端就默认你已经准备好了用于直出渲染的数据,余下的 callback 将直接忽略。等到了客户端之后,初态函数会再被执行一遍,以补充剩余的 callback 调用。这样一来,我们只需要把主接口数据放在第一个 callback 调用,次接口数据由第二个 callback 调用,就能实现主次接口数据的分端请求渲染了。


八、总结

1.页面搭建系统的开发心得

1.1 严谨设计

相比独立开发一个页面,搭建场景的开发可能随时随地都要求着严谨的设计。任何你认为的微不足道,如果不引起重视,最终都可能被放大,成为一个绕不开的绊脚石,阻碍你的系统进一步迭代优化。


1.2 重视规范

很多时候我们的设计,比如今天讨论的数据模型解决方案,并不是什么高深的技术,包括数据源的编写、三端同构流程,更多只是一套开发范式。搭建系统需要考虑的东西远比独立开发场景多得多,有了规范约束,才能更加自如地面对迭代和协同开发。


1.3 重视统一

独立和统一并不矛盾,并不是说搭建场景就是一切务求独立。相反,独立和统一是相辅相成的,虽然搭建的目的是自由组合,但在设计开发时却必须足够重视统一的思想。


2.关注我们


最后,感谢大家的观看,欢迎扫码关注我们的技术团队 WecTeam,给你带来更多技术分享。



近两年 Scott 观察到前端行业已经完全进入竞争的深水区,各大小公司的前端 TL 刚刚上任,初带团队,针对前端工程师这个群体,应该怎么管人理事,搭台拿结果,帮带有成长,就成立了这个前端技术主管学习交流群,在人的选用育留上互相学习成长,入群的门槛是你有实线或者虚线在带团队,请加 Scott 微信: codingdreamer 邀请入群:
看完若有启发,就请点赞评论转发三连吧

关键词:实现,系统,模型,设计,数据

74
73
25
news

版权所有© 亿企邦 1997-2025 保留一切法律许可权利。

为了最佳展示效果,本站不支持IE9及以下版本的浏览器,建议您使用谷歌Chrome浏览器。 点击下载Chrome浏览器
关闭