查看原文
其他

爱奇艺页面动态化组件方案的演进

爱奇艺 爱奇艺技术产品团队 2021-10-12

导读


一直以来,移动端应用都在不断寻求页面动态化解决方案

为什么需要动态化?




  关于移动端应用需要动态化的原因,归结起来有:


  • 快速的业务迭代:在当下的互联网行业,敏捷开发是主流的模式,小步快跑,快速迭代是常见开发节奏,但是即使每周一次发版迭代(实际上多数应用达不到),某些功能的产品周期还是过长


  • 应用市场审核:尤其是对于iOS应用,由于要Apple的审核,正常情况下提交到用商店后,需要等待一段时间来审核


  • 新版本用户升级慢:新版本发布后,更新覆盖到所有用户需要较长的时间


  • 强运营需求:各种强运营需求,如A/B Test分区内容运营等也需要动态化的能力。


所以,对于主流大型移动端应用而言,动态化几乎可以认为是刚需,爱奇艺自然也不例外。本文就爱奇艺移动客户端团队在过去几年业务快速发展的过程中,页面动态化方面的实践和探索进行分享,共同进行交流讨论。


爱奇艺移动端的动态化大概经历了下面几个阶段:


1.  初步动态化,内部代号Card 1.0方案 

        

2.  将行为与数据规范化统一的动态化,内部代号Card 2.0方案

         

3.  引入模板和样式的概念,将结构与样式分离,进一步将UI组件动态化。支持组件与样式复用,支持任意层次挂接事件,支持统一的事件处理框架和pingback框架,内部代号Card 3.0方案


4.  借鉴大前端的思想,引入布局描述的概念,舍弃自定义DSL,使用XML格式描述布局。排版方面,支持双层flex排版。事件逻辑方面,引入脚本语言,支持动态下发逻辑。 内部代号Card 4.0方案


整体演进脉络如下图所示:


下面分别就各个方案做介绍


Card 1.0方案:



该方案中,页面按照一定的规则拼接成json格式的数据,各字段按照功能类别划分成一些json节点,并构成层次关系,主要分为头部结构、内容结构、以及一些控制结构等。客户端请求后端得到数据后,对这些数据进行筛选、解析、拼接,并与UI控件进行绑定,最后显示到屏幕上。


Card 1.0方案较好地解决了数据动态组织的问题,并且支持了初步的显示控制。但也存在明显的不足之处,主要体现在:


   1.  客户端需要筛选返回的数据,逻辑复杂


   2.  客户端需要做很多拼接工作,并且没有规范化的处理方法


基于上述这些不足,我们很快发展了Card 2.0方案


Card 2.0方案:



Card 2.0方案可以看成是一套页面元素组织显示规范:整个页面切分为一系列称为card的组件,card组件作为前后端复用组装的基本单元。每个card组件由4个可以自由组合的部件构成,即标题栏(top_banner)、尾栏(bottom_banner)、分隔栏(gap)、内容区(container) ,如下图所示:


Card 2.0方案的优点是概念相对简单,UI结构清晰,客户端实现高效,其很好地满足了一段时期内的动态化需求。但是随着业务的不断扩展,特别是功能和交互的复杂化,也逐步暴露了一些问题,如:


  • card种类膨胀:以整个card作为组件复用的单元,复用的粒度过大,导致实际复用率不高,随着业务的扩展,card种类不断增多,直接导致了包大小膨胀的问题


  • 动态化不够,具体体现在:


其一,不深入:动态化在协议层面只规定到card级别,对于内部元素与事件的动态化并无涉及,实际的实现方式随着业务和开发人员的不同,也各不相同


其二,不规范,只能两端约定使用自定义字段、语意等,case by case实现,没有统一规范化的做法


  • 对多事件的支持不理想:由于Card 2.0协议的原始设计主要着眼于海报展示类

应用,对于事件的动态绑定设计比较简单,每个container item最初只能绑定一个事件,后期开发交互复杂的功能时,应对多事件的能力不足。


Card 3.0方案:




为了推进动态化方案的继续发展,在总结Card 2.0协议实施情况的基础上,我们着手设计Card 3.0方案,在项目启动之初,确定了Card 3.0的如下目标:

 

  • 细粒度:

降低组件的粒度,最基本的复用组件从card减小为block


  • 结构样式分离:

引入了card模板和样式表的概念,将结构与样式分离。其中card模板负责描述整个card的骨架信息,如定义每行block的数量及占比,分割线的显示等;样式数据负责描述控件的详细样式;card模板和样式表再结合页面数据,构建整个页面的UI结构。


  • 灵活、复用:

card模板、样式表以及页面数据都支持动态投放

card模板和样式在多个card间复用


下面是一个应用Card3.0方案的页面UI结构简图:

其中

page:代表整个页面


card:逻辑分割单元,通常用来对不同的数据来源、不同的功能类别进行归组划分


block:基本的UI复用单元,表示一个相对稳定的UI组件,如图片+若干描述,播放器+描述等。通常建议按照UI组件的通用程度来进行拆分


control:封装的基本控件,主要有图片、按钮、简单文本、富文本、播放器等,支持业务层注册自己的控件


除了上述主要组件,还有seprator(横向分隔组件),gap(block之间的分隔组件)等,其样式(宽高、颜色等)都由样式表进行控制


Card 3.0协议的整体架构如下图所示:



card模板和样式表的动态更新:


card模板和样式表通过统一的接口进行更新。由于card模板和样式表的更新接口与页面数据接口是互相独立的,为了解决可能出现的数据不一致的问题,在请求页面数据时,将本地card模板和样式表的版本作为参数带到后端请求中,后端筛选与当前模板和样式兼容的页面数据,下发到客户端,整体过程如下图所示:



事件处理与级联:

在原始数据中,行为事件是由行为数据来描述的。行为数据描述了行为事件(点击、滑动、摇一摇等)发生后,所触发的行为和所需要的参数,行为数据关联到控件上,控件在触发所指定的行为时,框架会执行相应的事件。


为了统一处理同一控件在不同事件之间,样式和行为的切换,设计了事件级联协议。大致的思路是,下发多个控件样式描述及跳转路由表,抽象所有行为数据对应的事件的执行结果,根据执行结果结合路由表决定事件和样式的切换路径。举个例子,如订阅按钮,其初始样式为“订阅”,其行为数据是执行订阅动作,对应一种UI样式,如果订阅成功,其行为数据应该切换为“查看更新”,并对应于另一种UI样式;如果订阅失败,其遵循另一条切换路径。通过事件级联协议,上述过程完全可以统一自动处理。级联事件的原理如下图所示:



上述过程只是一个最简单的例子,实际上级联协议支持任意事件间的任意次跳转。


Card3.0是目前爱奇艺移动客户端主力动态化方案,应用非常广泛,大部分基线频道页面都应用了该协议。


Card 4.0方案



一方面,随着大前端概念的兴起,越来越多Web概念被引入到移动开发领域,如RN和Weex,Web前端的一些概念和工具确实能在某些方面提高开发效率,值得传统移动客户端开发人员思考和借鉴;另一方面,随着Card 3.0方案在爱奇艺移动端双平台(iOS、Android)各业务的大规模落地,逐步暴露了一些需要改进的地方,主要体现在:


1.  自定义DSL学习成本高,应用范围较为狭窄,小规模团队内部使用问题不大,但是当大规模推广到其他团队时,会面临学习成本高,需要反复培训的问题


2.  随着落地页面的增多和样式交互的复杂化,样式配置也越来越复杂,在多个团队同时使用时容易冲突,即使配套开发了样式管理平台,还是只能在一定程度上缓解该问题。


3.  落地形式以完整页面为单位,不支持与原方案混排,侵入性大


4.  对后端数据协议依赖性高,对其他数据结构的适应性差


5.  不能动态下发逻辑


基于上述情况,在上一代方案的基础上,我们进一步发展了Card 4.0方案,相对以前方案,有如下特点:


1.  通过XML格式的布局文件描述组件单元,由解析器负责解析创建


2.  排版遵循flex描述,舍弃了之前维护成本很高的自定义模板


3.  组件单元的组合使用了基于flex规则定义的layout pattern协议


4.  组件解析生成后进入自定义复用池,支持多种复用模式,高效复用


5.  支持业务层注册自定义Tag组件


6.  支持业务层注册自定义属性


7.  支持样式预解析及异步排版,提高解析排版效率


8.  支持多种落地方式,如Card页面、Card混排、Block混排、结构化非Card列表,独立UI组件等,方便以多种形式与原有业务结合,侵入性低


9.  业务逻辑引入Lua/JS脚本,支持一定范围内动态下发逻辑


Card 4.0的整体架构如下图所示:


其中Skin Designer是为了方便布局文件生成而开发的一个工具,支持通过拖拉拽的方式生成布局文件;


Hot Swap是热更新模块,动态更新布局和脚本资源


目前Card 4.0方案已经落地到爱奇艺移动客户端多个线上业务,如儿童频道、VIP频道、钱包模块等,其学习成本、开发效率、性能表现均优于上一代方案,目前正在更多业务铺开。


总结



纵观card方案演化的整个过程,不难发现一直是按照下面的规律来进化的:


  • 粒度的不断细化,从整个card组件,到block组件,再到基本的原子控件


  • 描述的规范化,从自定义DSL到通用描述式(XML布局文件,flex排版

    某种程度上脚本也可以看作是一种规范化的配置文件)


  • 动态化,将静态特性转化为动态化配置进而脚本化,动态化能力不断增强



目前Card 1.0协议已经完全退出;Card 2.0协议存在少量遗留页面,即将完全退出;从业务占比上看,Card 3.0协议是目前的主力,但是正在被Card 4.0协议逐步替代。


上述过程是一个业务驱动的过程,同时也是一个技术驱动的过程,几个方案在不断演化的同时,支撑了近几年爱奇艺移动端大多数业务的发展。


需要指出的是,本文主要讨论的是方案的客户端部分,移动后端团队为方案的快速高效落地也做了大量的工作,提供了很多方便的工具,如模板系统、自助式样式配置系统,支持预览的Card配置平台等。


后续规划



一方面,将进一步扩大Card 4.0方案的应用范围,通过更多业务的迭代推动方案的完善与成熟;


另一方面,将完善相关的工具,如布局生成器、支持布局、样式hot reload的调试器等。


此外,在完成文档和样例建设后,Card 4.0方案会逐步开源,敬请期待。


: . Video Mini Program Like ,轻点两下取消赞 Wow ,轻点两下取消在看

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

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