全球购海豚系统在提效探索过程中选择了楼层化自定义布局的模式,在上篇中,我们介绍了从配置平台到服务端的模块设计,这篇中将重点介绍前台展示逻辑,主要从客户端的角度阐述自定义布局如何从数据解析到界面渲染,最后完成内容更新。
在介绍客户端自定义布局实现前,先看下京东国际频道主页的整体结构。主页由5个Tab页构成,分别是“国际”、“品牌”、“种草”、“分类”、“自营”,拿“国际”Tab页为例,它下面又分为“首页”、“美妆”、“母婴”等13个类别子tab页面,每个子tab页中展示各种业务功能,涵盖商品展示、用户拉新、广告推送和运营活动等,它们都以楼层的形式纵向排列在页面上。如图一所示,预发环境”首页“中展示了头部广告轮播楼层、百宝箱楼层、品牌动态楼层以及优惠券楼层,图二是频道主页的树形结构。其中品牌动态楼层是自定义布局的,与其他固化模板楼层无差别的展示在页面中。
图一 预发版京东国际频道页面
图二 预发版频道主页树形结构
如何做到自定义布局的楼层和模板楼层无差别展示呢,海豚系统在接口定义上做了一个巧妙的处理,首先每个楼层除了共有属性以外,私有属性都封装在一个以widget结尾的对象中,然后运用数组将楼层数据集合在一起。自定义楼层也一样,除共有属性外,私有属性都被封装在一个叫flexWidget的对象中,在布局接口中flexWidget对象存放自定义布局数据,在内容接口中flexWidget对象存放自定义内容数据。由于自定义楼层和普通模板楼层具备相同的结构,唯一不同的是widget对象,所以楼层创建逻辑一致,楼层内部渲染各自处理。
下面就来重点介绍自定义楼层在客户端的实现,首先从数据请求开始。客户端启动数据请求模块开始请求数据,界面展示loading状态,随后通过布局接口下发的布局数据完成界面布局初始化,通过内容接口下发的内容数据完成内容展示(界面更新)。由于数据被解耦成了两个接口,所以存在数据先来后到以及加载失败的问题,主要分为以下四种情况:
1、 布局数据先到,内容数据后到;
2、 布局数据先到,内容数据加载失败;
3、 内容数据先到,布局数据后到;
4、 内容数据先到,布局数据加载失败;
1和3是两种正常的数据接收情况,但是它们的处理方式有较大的区别,先介绍1布局数据先到内容数据后到的情况。在这种情况下客户端获取到布局数据后,为充分利用内容数据加载的等待时间,随即启动布局初始化模块,由于布局数据被设计成了模拟真实布局的嵌套结构,所以在初始化界面布局时,初始化模块只需先找到根容器,然后从外向内一层层递归渲染即可,每一层子视图会按照在配置平台设定好的渲染顺序进行有序渲染,当子容器中有子容器,那么将子容器节点后的所有布局数据作为参数再传递给渲染模块,完成子容器内子视图的渲染。就这样一层层递归下去,直至所有叶子节点的视图完成渲染,这样界面布局的初始化就完成了。
但是到这一步还没有结束,为了界面能展示丰富的内容,需要用后获取到的内容数据进行界面更新。初始化各视图时只是使用了默认数据进行展示,像图片视图只是预留了空白区域或显示了默认占位图,文本视图只是预留了文本展示区域,并没有显示任何文本。上面介绍过,内容数据和布局数据是解耦的,它们仅仅通过控件id建立起联系,为了达到类似初始化布局时由外向内一层层递归的方式更新界面内容的目的,内容数据也被设计成了模拟真实布局的嵌套结构。在更新视图展示内容时,更新模块也是先找到根容器,然后通过id检索子视图内容数据,为已初始化的子视图完成赋值,有子容器的情况,就将子容器节点后的所有内容数据作为参数再传递给更新模块完成子容器内子视图的赋值。这样,客户端在执行布局和内容双递归流程后,移除loading状态就完成了整个界面的展示工作。
下面再介绍下3内容数据先到布局数据后到的情况,在这样情况下,由于布局数据还没有获取到,所以界面继续展示loading状态,初始化模块会等待布局数据的到来。虽然内容数据已获取到,但是界面并没有被初始化,更新模块也不会启动更新流程。等到布局数据来到后,数据解析模块会把布局数据和内容数据进行整合,按照原有的嵌套关系整合到一个带布局和内容数据的结构中。简单说就是将上篇图六中的两部分数据合二为一,相当是给布局数据里加入了内容数据,如下图三所示,这样能将原先两次嵌套递归流程合并为一次。
图三 合并后的数据结构
接下来处理流程就跟情况1中界面初始化一致了,情况1中初始化时布局数据里是没有内容数据的,现在有内容数据后,就可以在初始化各视图的同时完成视图的赋值工作。最终移除loading状态,展示动态渲染出来的界面。
2和4是两种数据获取异常的情况,在数据获取异常时会有重试机制,无论是布局接口还是内容接口数据获取失败的情况,都会启动重试机制,一般设定重试次数为2次,如果重试过程中数据被正确获取到,就会遵循数据获取到的先后顺序执行上述1或3的渲染流程。如果重试次数用完,数据加载还是失败,那么页面将从loading提示状态转为页面加载异常提示状态。
客户端完整的自定义界面渲染流程如下图四所示:
图四 自定义界面渲染流程
后续如果界面布局未发生改变,但内容发生了变化,服务端在客户端刷新界面拉取数据时通过客户端传入的接口入参决定是否仅下发内容数据,该入参会指示服务端,客户端本次数据请求仅仅是内容刷新还是界面初始化渲染。如果是后者,那么客户端将执行整个动态界面渲染过程;如果是前者,客户端两个接口中,只有内容接口会获取到数据,布局接口除了返回告知客户端布局数据未变化的状态字段外,不会带有任何布局数据。拿到刷新的内容数据并解析后,客户端将完成一次内容更新的递归流程,类似上述情况1中的后半段内容更新过程,具体流程如上图四中蓝色路径。
到此,海豚系统自定义布局的全部内容就介绍完了,回顾上篇和本篇内容,我们主要介绍了自定义布局在海豚系统中的架构和模块设计,以及从配置平台到服务端再到前台的工作流程,整体上有了一个较为清晰的认识。配置平台决定自定义楼层的布局、数据关联,动态化服务负责将配置信息分离成布局数据和内容数据,并格式化,前台负责将数据转化为楼层进行展示,形成了一套完整的闭环系统。
目前,海豚自定义模块已经在频道页完成多轮灰度并最终切量上线,618期间我们完成了多达20次的活动模块配置,通过监控分析包含黄金眼、烛龙、阿凡达、用户之声等多个平台采集的数据,海豚自定义楼层数据表现良好。接下来,我们会从以下几个方面持续完善和建设海豚自定义模块。
1、丰富自定义模块素材配置能力,实现并完成与通提投平台的对接,并提供其它外部平台打通的能力。
2、丰富自定义模块基础能力,完善该模块对联动、滑动等复杂能力的支持,扩大自定义在业务方的支撑范围。
3、完善自定义模块数据展示,提供包含埋点、崩溃率等多项指标为一体的监控平台。
4、努力向着开源共建的目标建设,提升团队整体影响力。
Copyright© 2013-2020
All Rights Reserved 京ICP备2023019179号-8