如何设计实现 H5 页面搭建系统 - 数据模型

如果无法正常显示,请先停止浏览器的去广告插件。
分享至:
1. 如何设计实现 H5 ⻚页⾯面搭建 数据模型 京东京喜前端团队 沐童
2. CATALOG ⽬目录 01 MPM 整体介绍 02 数据层⾯面临的痛点 03 ⻚页⾯面模型设计 04 请求模型设计 05 总结
3. 01 MPM 整体介绍
4. 上线服务4年年+,系统迭代超3个版本 Mart Page Maker 累计使⽤用⼈人数1400+,搭建⻚页⾯面1.9w张 除⽇日常活动外,承担80+%的⼤大促会场 H5 卖场可视化搭建系统
5. MPM能⼒力力概览 搭建物料料丰富 MPM 现有 30+ 个组件、500+ 个模板,业务能⼒力力覆盖商品、导 购、营销等多个场景。 配置功能强⼤大 三端渲染是 MPM 的强⼤大能⼒力力,除此之外,MPM 还⽀支持⻚页⾯面配 置 BI 排序、⾃自动化埋点、⾃自动化测试、⻚页⾯面测速等。 系统能⼒力力全⾯面 MPM 为⻚页⾯面保驾护航,不不但配备了了流畅的拖拽编辑器器、实时预 览和⻚页⾯面健康诊断能⼒力力,还对系统和⻚页⾯面做了了全⽅方⾯面的监控和容 灾降级⽅方案。
6. MPM效果展示 2、选择你需要的 模板 1、从这⾥里里拖⼀一个 组件到预览区
7. MPM效果展示 4、发布⻚页⾯面 3、配置楼层组件 属性
8. MPM效果展示
9. MPM系统架构
10. MPM⼯工作流程
11. 02 数据层⾯面临的痛点
12. 解决场景 “ 请求散乱⽆无章 ⻚页⾯面请求茫茫多,有时候想定 位⻚页⾯面中某个请求来⾃自哪个组 件,可能得定位半天…… 卖场承载各线业务,接⼝口场景繁杂,如果简 ” 单地将请求交给组件⾃自身各⾃自发起和处理理, 维护起来⼗十分麻烦。
13. 解决场景 “ 多余的重复请求 某个⻚页⾯面,多个组件都配置了了 同⼀一个预约 ID,导致⻚页⾯面发出 了了 N 个⼀一模⼀一样的预约状态查 询请求…… 缺乏数据请求统⼀一管理理的后果就是,这些⽆无 ” 效的重复请求将严重拖垮你的⻚页⾯面性能。
14. 解决场景 “ 接⼝口压⼒力力⼤大 商品接⼝口⽀支持批量量请求,可我 们⻚页⾯面中多个商品组件的接⼝口 请求并没有合理理聚合,⾛走批量量 调⽤用…… 同个⻚页⾯面经常会多次请求同个业务接⼝口,这 ” 对接⼝口服务造成了了⼗十分⼤大的压⼒力力。
15. 解决场景 “ 数据模型多变 商品组件下的各个模板,除请 求商品之外,有些模板会拉取 新⼈人价,有些模板会拉取补贴 价…… 组件对应多个模板,每个模板都可能对应了了 ” 不不同的数据模型。
16. 解决场景 “ 三端同构诉求 以 Vue 为例例,我们习惯在组件 created 时请求数据,这在客 户端渲染时⼗十分完美,但在直 Vue ⽀支持 SSR,但却⽋欠缺对异步数据获取的 出场景却完全⾏行行不不通…… 同构⽀支持,为了了适配 MPM 的三端同构,数 ” 据层设计必须考虑这个问题。
17. 定义 为⾃自搭建卖场打造的⼀一套⾼高效通⽤用的数据请求解决⽅方案 1 2 3 统⼀一管理理 ⾃自由组合 适配三端 维护请求秩序,优化 请求性能 数据模型即插即⽤用, ⾃自由组合 为三端同构提供统⼀一 的数据请求⽅方案
18. 03 ⻚页⾯面模型设计
19. PageData PageData 是⻚页⾯面的抽象描述层 解析引擎 PageData ——————> 真实⻚页⾯面 interface iPageData { pageId: number; ⻚页⾯面级配置 1)⼀一些基础配置,⻚页⾯面级别的请求,如楼层 BI 排 序查询在这⾥里里发起。 2)⻚页⾯面对⽤用户身份的要求配置,⽤用户级请求,如 ⽤用户身份查询在这⾥里里发起。 组件级配置 包含了了组件楼层的配置,因此这份配置决定了了组件 楼层的业务数据获取。 // ⻚页⾯面id ⻚页⾯面配置 基础信息配置 搜索配置 分享配置 pageConfig: { basic: iBasic; search: iSearch; share: iShare; }; // // // // userConfig: { checkNewUser: boolean; }, // ⽤用户配置 // 1)是否需要查询新⼈人 componentConfig: iComData[] // 组件配置 }
20. ComData ComData 是 PageData 的核⼼心部分 模板配置 指定使⽤用某个模板,引擎将根据这个配置使⽤用相应 的组件模板进⾏行行渲染。 数据配置 楼层配置数据,这⾥里里包含了了组件请求接⼝口所需的参 数。 组件关系 描述了了组件的⽗父⼦子级对应关系。 interface iComData { uid: number; source: string; data: object; styleKey: string; parentUid: number; children: iComData[]; } // // // // // // 组件id 数据源标识 组件配置数据 组件模板id ⽗父组件id ⼦子组件
21. 04 请求模型设计
22. 数据源及请求优化策略略 - 统⼀一管理理 + ⾃自由组合 -
23. 数据源 数据源是请求模型的基本单位,描述了了⼀一类请求动作 接⼝口地址 1 每个数据源对应了了⼀一个接⼝口 请求后置处理理 请求响应后的⼀一些通⽤用的数 据处理理逻辑 聚合分发策略略 描述了了如何对多个同接⼝口请 求作请求聚合和响应分发 请求前置处理理 2 3 发起请求前的参数组装处理理 4 5 6 ⼊入参校验 对⼊入参进⾏行行校验,不不合法⼊入 参将不不会发起请求 监控统计配置 接⼝口监控、统计相关的配置
24. 数据源 // 数据源模型 数据源是⼀一个 class,以配置数据 为参,实例例化后可以得到⼀一个请求 对象。 每个数据源都有⾃自⼰己的名称标识, 调⽤用层通过指定数据源标识,来选 择调⽤用某个数据源。 interface iDataSource { url: string; // 请求地址 params: object; // 请求参数 verify (params: object): boolean; // 参数验证 beforeRequest (config: MPMComConfig): any; // 请求前置处理理 afterResponse (result: any): any; // 请求后置处理理 batch: iBatch; // 聚合分发策略略 monitor: iMonitor; // 监控统计配置 } // 组件/模板直接调⽤用数据源获取「商品」 dataServive.fetch({ source: 'skus', ...data })
25. ⾃自由组合 1 数据源理理应纯粹⽽而专⼀一 数据源应该只做⼀一件简单的事,⽐比如请求响应的⼀一些通 ⽤用处理理,特殊业务逻辑不不应该在数据源中出现。 2 ⾼高级请求模型由数据源组合⽽而成 复杂的请求模型可以由多个数据源组合⽽而成,调⽤用层可 以直接调⽤用数据源,也调⽤用封装好的⾼高级请求模型。
26. ⾃自由组合 // 商品 + 优惠券 请求模型的组合采⽤用最简单灵活的 函数调⽤用,这种组织⽅方式对多变的 请求模型⼗十分有利利。 向上,我们将调⽤用⽅方式对⻬齐,对开 发者来说,调⽤用单⼀一数据源还是⾼高 级请求模型,没什什么区别。 async skuWithCoupon (data) { // ... const skus = await dataServive.fetch({ source: ‘skus' }); const coupons = await dataServive.fetch({ source: ‘coupon' }); // ... return result; } // 组件/模板间接调⽤用数据源获取「商品+优惠券」 dataServive.fetch({ source: 'skuWithCoupon', ...data });
27. 统⼀一管理理
28. 请求优化策略略 避免重复请求 依靠⼀一个简单的请求队列列 和请求缓存,我们有效避免了了 ⻚页⾯面内发起重复请求
29. 请求优化策略略 请求的聚合分发策略略 interface iBatch { limit: number pack: (actions: Action[]) => Action unpack: (result: any, actions: Action[]) => Record<ActionMd5, ActionData> } 数据源可制定聚合分发策略略,使得 1 同类请求对象在发出前经 pack 合 并,响应后经 unpack 拆包分发 引擎以队列列收集请求对象,会等到下 2 ⼀一个 Tick 再发起请求,在这个 Tick 中,如果队列列超限,就会提前发起
30. 请求优化策略略 合并同类请求 每个数据源可定制⾃自⼰己的 聚合分发策略略,以此让同类 请求合多为⼀一
31. 初态函数 - 三端同构 -
32. 假如不不考虑同构 灵魂拷问:前后端渲染有什什么区别? 我想把客户端渲染那⼀一套,照搬到直出端,为什什么不不⾏行行?
33. 假如不不考虑同构 客户端的渲染流程 客户端允许存在多趟渲染,中间以⻣骨架屏占位,渲染与请求没有严格的先后顺序
34. 假如不不考虑同构 直出端的渲染流程 直出端只有⼀一趟渲染,渲染前要求数据全部到位,所以请求必须在渲染之前完成
35. 假如不不考虑同构 结果你直出了了⼀一份⻣骨架屏? 如果你把客户端渲染直接搬到直出端,很遗憾,你可能就只能直出⼀一份⻣骨架屏
36. 基于三端同构的请求模型 1 同构的关键在于初态渲染 前后端同构的关键就是初态渲染,也就是⻚页⾯面的初始化渲染阶段。 2 补充适配直出端的⽣生命周期 Vue 现有⽣生命周期没有任何⼀一个能够满⾜足直出端的异步数据获取, 要实现直出,数据模型就必须补充适配直出渲染的⽣生命周期。 3 三端解析流程应保持统⼀一 要实现三端同构,我们还需要规范解析流程,让三端解析渲染流 程保持⾼高度统⼀一。
37. 初态函数 位于组件⽣生命周期之前的异步函数 interface iMPMComponent { // ... getInitialState (config: MPMComConfig): Promise<MPMComData>; // ... } 1 每个 MPM 组件都有⼀一个初态函数, 三端引擎在创建组件实例例前,将先收 初态函数以组件配置数据为⼊入参,异 集执⾏行行各组件的初态函数,并将函数 步返回⽤用于组件初始化渲染的初态数 据。 2 的异步返回结果作为组件初始化渲染 的数据。
38. 基于三端同构的解析流 静态 H5 / ⼩小程序端
39. 基于三端同构的解析流 直出端
40. 初态请求优化 刁钻场景:主次接⼝口分端渲染 我有⼀一个组件,串串联请求了了主、次两个接⼝口,可是次接⼝口内容没那么重要,为了了提⾼高直出效率, 能不不能只直出主接⼝口,次接⼝口等到了了客户端再请求呢?
41. 初态请求优化 主次接⼝口数据的分端请求渲染 主次接⼝口串串联时,主接⼝口在直出端完成,次接⼝口在客户端补充,提⾼高直出速度 interface iMPMComponent { // ... getInitialState (config: MPMComConfig, callback: (data: MPMComData) => boolean): void; // ... } 1 初态函数的第⼆二个参数是⼀一个回调 对于这类初态函数,直出端只会响应 函数,传⼊入初态数据并执⾏行行可以触 第⼀一个 callback,余下的 callback 将 发引擎⽴立刻渲染,因此,利利⽤用它可 以实现初态数据的分段渲染。 2 直接忽略略,等到了了客户端之后再作执 ⾏行行,补充初态数据。
42. 05 总结
43. 01 相⽐比独⽴立开发⼀一个⻚页⾯面,搭建场景开发可能随处都要求着严 02 数据模型解决⽅方案更更多只是⼀一套开发范式,没有规范约束的 03 独⽴立和统⼀一并不不⽭矛盾,虽然搭建的⽬目的是⾃自由组合,但在设 谨的设计,任何你认为的微不不⾜足道都不不应该被忽视 搭建系统是不不可维护的 计开发时却必须⾜足够重视统⼀一的思想
44. THANKS 感谢您的观看 欢迎关注我们
45.

Home - Wiki
Copyright © 2011-2024 iteam. Current version is 2.139.0. UTC+08:00, 2024-12-23 12:14
浙ICP备14020137号-1 $Map of visitor$