查看原文
其他

京东App MCube动态化实践

薛盼杰 于威 京东零售技术 2022-06-25

引言

在京东App里,消费者购物的关键环节包括搜索、商品详情页、购物车、结算下单到订单等,在整个购物链路中属于价值非常高的部分,因此被称为黄金流程(以下简称黄流)。而随着业务的高速发展,为了用更快的响应速度、更少的研发人力、更好的用户体验承接业务需求,“动态化+跨端”自然而然进入我们视野。在此基础上,我们结合黄流业务对于性能和稳定性要求极高的特性,输出了一套原生动态化方案,代号“MCube”,截止到目前,已在App内多个业务模块上线。




MCube 特点与优势


01MCube 目标


MCube 致力于提供一个完整的跨端原生页面动态展示的技术解决方案,使得业务可以基于 MCube 做到一次开发,随时上线,多端复用的效果。另外基于 MCube 代码的复用也可以缓解业务不断增加带来的包体积问题,同时解决 Native端新增需求或者需求变更强依赖发版的痛点。

目前随着 MCube 的不断完善,已经形成支撑亿级流量的高稳定架构,并且正逐步发展为以动态化架构为核心,质量保障、效率提升、性能优化、数据埋点等多维度辅助的一整套生态平台。


02技术选型


随着大前端的发展,我们需要选择一个拥有前端亲和性、两端表现一致性以及高性能的方案,经过横向调研业界实现方案,综合我们的各种诉求,确认了三个方面的选型:布局引擎、开发方式、二/三方库对接。


图1 业界方案横向对比


布局引擎方面,首先考虑的是两端布局一致,同时降低开发者学习成本,在经过对性能的测量后,决定选择使用实现了FlexBox 盒式布局的三方库Yoga作为我们的布局引擎。


图2 性能对比数据


从上图可以看到,FlexBox布局与理论上耗时最短的Frame布局基本持平,并且在复杂视图布局上的表现,一定程度上优于iOS自动布局技术AutoLayout。

在实际使用过程中我们也解决了一些 Yoga 存在的问题,例如 iOS ScrollView 崩溃问题、Android visible 支持以及图片适应等。

在开发方式方面,我们选择了 XML 作为视图 DSL格式,并设计了一套对于各种基础原生控件的描述。为了达到一套模板双端展示一致效果的目的,对Android 和 iOS 端的属性表现差异进行抹平对齐。同时为了降低模板文件的宽带占用,提高解析效率,我们将XML进行编码传输。使用我们特有的编解码技术可以将压缩率控制在 60% 以内、处理时间缩短 70% 以上,增加了协议传输的安全性与防篡改性。


图3 MCube桥接设计


二/三方库对接方面,如图3所示,我们设计了协议层对接各个可插拔的组件,将 SDK 的一些基础能力如网络、数据库、文件、埋点、图片加载等进行接口抽象,使得业务接入时可以方便的代替为自定义的基础能力。


03MCube 平台架构


MCube架构不断演进,已经形成支撑亿级流量的高稳定架构,并且正逐步发展为以动态化架构为核心,质量保障、效率提升、性能优化、数据埋点等多维度辅助的一整套生态。接下来根据 MCube 能力全景图进行进一步解析。


图4 MCube 全景图


1 、容器

MCube 的端侧容器架构设计遵循了分层架构的设计,将 MCube 分为了引擎层、视图层、事件层以及模板层:

1. 引擎层,这一层面主要为 MCube 提供底层支撑。渲染引擎,负责将抽象的节点映射为原始视图并进行渲染;布局引擎,将视图 DSL 解析为视图树方便进行后续渲染使用;表达式引擎,负责将接口数据与视图布局进行数据绑定,并处理一些逻辑交互;JS引擎,负责复杂逻辑的处理,动作扩展等;

2. 视图层,视图层主要职责是将抽象的视图解析为原生对应的视图,同时对属性解析和赋值(取值过程可能会用到表达式引擎解析),同时视图层也支持业务方注册自定义视图进行展示,可以方便的复用现有的视图能力,在得到完整的视图之后使用渲染引擎进行渲染上屏;

3. 事件层,该层主要负责对用户设置的事件进行处理,事件层会对 DSL 中的事件进行解析,解析后根据事件类型进行绑定,响应用户发起的事件动作做事件处理;

4. 模板层,该层主要职责为对模板的管理和使用,具体为对模板做出处理,例如模板下载,模板缓存,模板解析,模板兜底等操作。


图5 容器架构图


2、管理平台

MCube 管理平台提供了多方面的管理能力。系统管理方面,提供了各系统、各模块之间的隔离措施,保证业务可以对自己所在的模块进行模板管理,同时又不会对其他模块造成影响;安全管理方面提供了权限管控、审批流程等,共同保证模板上线的安全性。


图6 审核流程


3、开发套件

为方便开发者快速的学习、开发、调试,以及保证模板的正确性, MCube为开发者提供了多种开发提效配套设施。

1、 开发文档的建设可以方便业务方快速接入 MCube实现自己的业务。


图7 MCube 文档


2、 实时预览可以在开发过程中帮助业务接入方提高开发效率,同时也可以及时发现与解决问题。


图8 Android / iOS 实时预览


3、我们在Android Studio IDE上开发了MCube插件,提供样例模板拉取、模板创建、代码提示、代码校验、实时预览等功能,后续也规划了一键配置上传等功能。


图9 Android Studio 插件


4、 模板集市的建设可以方便业务接入时判断是否有同类型的业务已经接入,参照类似的业务完成快速开发上架。


图 10 模板集市


4 、质量

鉴于黄流业务的重要性,MCube 平台特别注重质量体系的建设,做了几方面工作保证整个链路的安全性。

1、 在发布管理上我们有灰度发布机制,灰度发布可以控制新版本的量级以及配置白名单验证回归支持等;

2、 根据各个业务模板的线上访问量,每个版本发布前我们会将高频次访问的模板内置进App内作为兜底模板。在运行时,当遇到模板下载失败、加载错误等异常时,回滚到兜底模板上,并配合异常告警机制,按需配置业务的降级策略,保证用户体验不受影响;

    

图11 回滚流程


3、 我们也根据核心流程制定了性能与成功率数据指标,通过对这些指标的监控和分析确保 MCube 本身的健壮性与稳定性。


图 12 指标口径


通过将核心流程划分为模板获取、模板加载、模板渲染三个步骤,并采用漏斗模型分析各个阶段存在的问题。基于对大量埋点数据分析,我们修复了若干复杂场景下的小概率问题,保障MCube高性能、高稳定地支撑亿级业务流量。


5、 共建

随着MCube在越来越多的业务中铺开,对于周边配套设施的诉求也越来越明显。我们将共建生态划分为了各个域,在整个集团范围拉通共建,邀请各个领域专家共同出谋划策,共同打造 MCube 的完整生态:

1、质量保障域,我们与测试团队共同规划了 MCube 在质量保障方面的一些共建工作,如,对于模板上线SOP、SDK升级自动回归等;

2、效率提升域,比如开发适配更多IDE的功能更丰富的插件;

3、性能优化域,比如如何使用异步渲染或者减少绘制图层等技术优化性能;

4、数据埋点域,比如如何结合动态化实现埋点的可视化、配置化;

5、产品设计域,比如如何快速将设计稿转成模板文件或者通过语义化的形式,降低底层UI的开发、适配成本;

6、Taro 共建,通过对接 Taro 框架,使更多开发者能够使用熟悉的框架(如React/Vue)来开发原生动态化。


动态化原理介绍


MCube端侧容器是 MCube 的核心支撑,下面我们就端侧容器的基本原理做出解析。


01渲染流程


MCube 的典型加载流程可以按照自顶向下的方式理解,首先 MCube 会依据模板缓存状态判断是否需要网络获取最新模板,当获取到模板后进行模板加载,加载阶段会将产物转换为视图树的结构,转换完成后将通过表达式引擎解析表达式并取得正确的值,通过事件解析引擎解析用户自定义事件并完成事件的绑定,完成解析赋值以及事件绑定后进行视图的渲染,最终将目标页面展示到屏幕。


图 13 整体加载流程图


02表达式引擎


MCube 表达式是为了丰富 XML 模板的各项能力的一个重要补充,使用表达式可以做到对属性的赋值,以及对相应视图的控制等功能。MCube 表达式的特点是支持无限嵌套,适合轻量级逻辑,解析效率高,性能相较于 JS 桥接有较大的优势等。


图 14 表达式架构图


03渲染性能优化


MCube 在使用过程中发现Android的渲染解析性能相较于iOS有较大差距。我们对整体流程进行打点分析,发现主要由于JVM的用时加载设计,导致冷启动时第一次渲染耗时过长。因此我们对 MCube 高频使用的组件例如 ImageView 、TextView、CollectionView 等,在APP启动后的子线程进行一次字节码预热,让相关类和方法提前缓存到JVM当中。经过对预热后的耗时数据分析,Android首次渲染用时缩短 60%+。


业务接入情况


目前MCube在黄流有广泛的业务实践,同时也赋能黄流外部的ISV共建方一种新的原生需求共建形式。下面分享我们在业务实际接入过程中的一些经验与收获。


01黄流业务实践经验


1 、应用场景

a.在保证原生用户体验的基础上不依赖发版、高效支撑业务需求:

目前客户端发版都有固定的周期,一旦错过某个版本,会导致业务需求的延期上线,MCube很好的解决了上述难题,因为它是一个高效的轻量级引擎,能够大幅提升人效。

搜索业务接入穿插卡片的万能楼层是一个例子。该需求用原生开发时,新增一种穿插类型需要开发大图和列表两种视图样式,并且需要处理服务端下发的穿插数据和Item关联的相关逻辑,这些工作需要iOS和Android开发各3天工作量。用 MCube开发模式时,只需编写包含大图和列表2个样式的模版,一套模版两端通用,只需2天工作量,提升人效超60%。

b.快速支持样式AB切量实验,随时更新页面样式和交互能力:

MCube支持同一个版本下创建多个模版样式进行切量实验,支持各业务模块的几百次业务快速更新迭代,包括样式间距调整、新增UI控件元素、业务事件逻辑变更、修改模版实时解决线上问题等。

c.有效控制APP包大小的增量。

无论是承接新的业务需求,还是改造替换已有的原生业务,都是APP瘦身的利器。


2、 原生页面内嵌动态化视图的接入方式

a. 在业务使用的实际场景中 MCube 提供预加载能力,预加载模板可以避免实际使用模板时,模板缺失带来的体验问题。重要业务我们会增加兜底模板,预加载失败会使用兜底模板满足业务,此时也会请求最新模板。

b.服务端下发的主数据唯一标识需与模版配置平台的唯一标识关联,通过主数据获取到对应的模版,然后将主数据和模版同时交给 MCube处理,将引擎渲染出的视图添加到原生的容器中。

c.对于列表中有倒计时、短视频逐一自动播放等需要以页面维度管理的高级功能,或模版中用到了一些原生的自定义属性时,则需要 MCube与原生进行通信,使用原生封装的通用型协议和方法去实现自定义功能。


3、 业务接入历程

为了保证线上业务的万无一失,我们在业务接入MCube时分为三个阶段。第一个阶段用原生页面兜底,MCube 逐步切到全量;第二个阶段用MCube本地模版兜底,MCube逐步切到全量;第三个阶段是可根据业务情况去掉兜底逻辑,使用网络下载模版。另一方面通过循序渐进的方式不断提升接入业务的复杂度,从简单局部视图到原生复用列表穿插动态化视图,进一步在原生页面嵌入全动态化列表,最终实现页面的全动态化。过程中,MCube沉淀了丰富的基础能力,如富文本、倒计时、视频控件、轮播图、排列视图、暗黑模式等。


4 、业务落地成果

目前动态化已经在搜索、推荐、商详等多个模块中使用,经过多次大促流量验证,同时在业务开发中不断沉淀新的样式模版到模版集市,为后续接入的业务模块提升模版编写效率。未来我们会不断优化业务接入成本,强化引擎基础能力,为更多的业务赋能。


图 15落地场景示例


02ISV共建新形式


MCube为部门外的ISV提供了一种更为便捷、可控的共建开发形式。相比于原生开发模式,MCube规范开发者仅能使用有限API,整体App的安全性更有保障。MCube相较于原生,学习成本更低,能够赋能前端团队开发以往只能编写原生代码才能开发的业务。如以下两个业务,均为共建形式进行的开发。

    

图 16  ISV 落地场景


MCube 展望


MCube 目前已经完成了基础能力的建设,逐步进入到技术与业务的深水区。

随着 MCube 使用场景的逐渐增多,在技术上我们会不断丰富能力,持续优化整体性能,进一步降低学习使用成本。另一方面我们也致力于提供更完善的配套设施,为此诚邀各个领域专家,在质量保障域、效率提升域、性能优化域、数据埋点域、产品设计域等方向共建共创,通力打造一个更加稳定、易用、完整的动态化生态,为京东集团业务赋能。

您可能也对以下帖子感兴趣

文章有问题?点此查看未经处理的缓存