乐趣区

关于移动端:哈啰动态化容器架构实践

背景介绍

哈啰的业务的多样性体现到 APP 页面上,咱们会发现整个 APP 的页面设计出现的形式产生了很大的变动。早些年哈啰 APP 页面的性能较为繁多,上图是近几年哈啰 APP 的页面,能够看出页面更加多样化,很多业务的性能和信息都在这些页面上展现进去,也有很多交互的能力。

这样的业务发展趋势及 APP 的页面设计形式,给咱们的技术团队带来了两个痛点和挑战。一是交付效率,复合型的页面往往会波及到多个业务团队的需要,也会波及到多个技术团队去合作开发,效率就会降落。同时,这些页面都属于流量曝光型页面,产品侧须要做产品的 AB 测试,尽快地去上线并回收数据。如果发现性能须要调整,产品就心愿尽快变更,所以用户触达效率及交付速度都对产品的迭代有很高的要求。二是用户体验,哈啰的首页及各个业务的一级频道页,都是一个业务最外围的流量页面,对用户的体验要求很高,如多端一致性、稳定性和交互晦涩度这些指标,绝对于其余三四级页面来说,对稳定性的要求也会更高。

技术计划

技术选型的两点思考

面临这些痛点和挑战,咱们想到了一些解决方案,首先介绍一下技术选型的思考。一是咱们要做一个架构,须要晓得架构的能力边界在哪里,要解决怎么的艰难和实现怎么的指标。这里列出了当初成熟的客户端 APP 的技术体系。从服务端来看,次要包含几个能力,最底端的是中间件的能力形象,下面是业务微服务的能力形象,再下面是面向端的能力形象,比方咱们通常会做一层 BFF 来面向端的接口封装,一层 CDN 来面向端的数据高效拜访的能力形象。从客户端来看,当初成熟的 APP 根本都有一套本人的组件化框架,做一些通用能力的积淀,咱们想要设计和实现的容器框架就是在组件化框架的下面,它的次要目标是承载各个外围页面的展示和相干的业务逻辑,这是整个容器的能力边界的大抵界定。咱们心愿这个容器首先是标准化的,通过标准化的伎俩来尽量抹平业务的复杂性带来的问题。二是隔离的虚拟化技术,尽可能进步本身运行的稳定性。这是容器的两个特点,也是咱们选定了在这个范畴做容器封装的技术。

咱们的容器既然要承载整个页面的渲染,应该用什么技术来实现动态化渲染,这是第二个技术选型的思考。其实业内也有很多成熟的技术计划。咱们能够从三个维度对这些技术进行归类,一是动态化能力,方才也提到这是很重要的思考点。二是原生体验,因为咱们对整个页面的晦涩度、稳定性都有极高的要求,如果在原生体验上做不到,那这个技术选型就不适合。三是开发成本,咱们的老本投入也是有下限的。比如说大家比拟相熟的 Web 容器的计划,是比拟容易引入到整个挪动端里的,它的劣势就是动静能力,相比整个原生的开发,它人造就具备动静更新的劣势。还有像 React Native、Weex 前几年也是十分火,它的技术选型是在整个原生体验和动静能力做了取舍。DSL 计划绝对于后面两种又各有劣势。咱们怎么去做技术选型次要有两个思考点,包含投入老本和要害收益。一是投入老本,要联合本人业务的状态和团队的人力投入来考量,它须要思考整个技术研发我的项目的老本,从头开发还是在已有的架构上做降级,老本是齐全不一样的。其次现有零碎的降级危险,对现有技术架构兼容性,对业务的影响都须要思考进去。二是要害收益,任何技术我的项目都有很多收益,咱们要思考做这个零碎,哪些技术能力是次要的,哪些是主要的,哪些是可有可无的。这样剖析后咱们能够看到为了保障用户体验,性能优先肯定是最先考量的要害收益。其次咱们要晋升效率,尽可能升高团队单干的边界老本。同时咱们心愿架构可继续地去演进,来满足业务一直增长的诉求。基于这两个思考,咱们最初抉择了 DSL 计划。

架构模型

挪动端的外围框架有渲染层、协定层和逻辑层。渲染层是解决动态渲染和动静渲染如何实现的,协定层是提供一些标准化的接口封装,不便模块的运行、通信以及扩大。逻辑层是整个容器框架本人运行的时候,它的状态治理、数据管理、日志治理各方面的一些能力的封装。监控层是整个容器框架本人内建的一套监控体系,咱们在这个体系上也搭建了很多可视化的工具和用户触达的能力。模块层更多的就是模块的治理。

动静模块的实现和优化

上图是容器渲染层动静模块的渲染过程。首先还是获取配置,也是方才整个页面配置里繁多模块的配置信息。这个信息里的次要格局有两局部,一是节点信息,决定了这一个渲染素外面每个节点的元素类型,它可能是一个空的容器、一个文本,也可能是一个图片。二是布局信息,咱们用 Flexbox 的语法来形容所有节点之间互相的关系。咱们把配置信息解析进去生成了配置树,就是把配置文件变成数据模型。接着是动静绑定,最初会生成一个渲染树。在这个过程中会遇到一些性能问题,如中低端的安卓机,渲染性能较 iOS 机型会呈现显著降落。

咱们从多个维度进行了优化工作,一是数据预取;第二是渲染优化,将前置的渲染操作步骤放到后盾线程来解决,并铺平页面元素的层级;第三个是数据更新策略的管制,包含版本治理、虚构节点、动静绑定和 Diff 算法。

咱们把这个卡片上屏之后,用户须要交互能力,于是咱们设计了一套 action 指令的形式来实现,通过预埋在配置信息里的路由命令来实现手势辨认和相应的页面跳转操作。action 指令能解决 80% 的场景需要,但在某些场景下不太好用。

比方这样的页面,有一个优惠券能够领,当点击红色去支付按钮的时候,卡片就会发生变化,比方按钮会置灰,卡片的款式也会发生变化。这种场景咱们通过实现一套 jsruntime 来进行反对,通过动静获取脚本来实现相似的操作。

容器逻辑层

这张图是容器逻辑层的模型图,能够从几个维度了解容器逻辑层的运作形式。第一是初始化,容器在启动时进行初始化,整个模块首先要进行自注册,咱们在适当时会获取相应的配置数据,接下来会走后面介绍的流程,依据模块的 ID 做模块的初创立,依据算法来判断是不是要上首屏,而后进行模块上屏。第二是运行时的状态,一个模块运行时次要有四个能力。一是它的布局和款式信息要维持,二是它的业务数据要维持,三是生命周期的状态,包含它的显示、暗藏、创立、销毁,四是事件监听,咱们基于一个模块通信的总线来实现整个模块状态的变更和互相关系的关联。此外容器有状态治理的机制。

容器协定层

第三层是容器协定层,咱们设计这一层的意义是想让模块开发更加标准化,无论是平台方还是业务方,能升高业务开发的复杂度。咱们次要形象了四层容器协定层,首先容器的布局协定和数据协定绝对比拟好了解,布局协定解决了布局的一些信息,如模块单元的大小、地位。容器的数据协定就是容器配置数据的填充,如单元格数量和内容;生命周期协定,包含创立、加载、显示、隐没和销毁。生命周期协定有很多利用的场景,比方性能监控和曝光计算。事件协定,事件总线的运行是依靠事件协定的,比方像模块事件、定时器事件。

容器运行

咱们从全局看一下容器运行是怎么做的,这里会看一下前端和服务端做的事件。前端会有一个配置平台。策略核心由算法驱动决定整个模块排序。业务微服务提供显示模块具体业务数据的起源,所有的信息都会交融成一个 BFF 层。端启动后,比方首页用了容器框架,启动之后它会做容器的初始化、模块的初始化流程,模块运行时又基于事件状态这样的管线来做一些状态的变更和模块的通信。

研发流程的改良

咱们设计了整个框架,新的系统对研发、测试、运维的工作形式都会带来很多的变动,很多环节上进行了生产提效。绿色标注的是挪动端惯例的发版流程,咱们看到波及到的节点和团队都十分多,跨团队的单干会遇到很多问题,发版速度并没有设想那么快。在新的零碎下,咱们通过在线零碎做的变更,这个环节的节点就会少很多,而且更新效率会快很多。

辅助工具

在整个开发过程中,咱们也做了很多工具来晋升开发的体验和效率。方才也讲到开发能够去配置平台做配置,咱们本地客户端也集成了一个调试工具,会预览渲染的动静卡片的款式。

公布和监控

公布上线的流程不同于传统的客户端发版,它变成了一个在线零碎的公布流程。除了公布的变更,咱们也做了一些监控剖析的能力为它保驾护航,咱们会采集性能的数据、稳定性的数据和异样的数据,在这些数据上建设可视化的剖析能力和告警触达能力。

我的项目实际

2020 年咱们做了首页大改版,整个页面会变成右侧这样。咱们心愿首页可能承载流量曝光、业务散发、广告营销各方面的能力,首屏的模块会变得十分多,所以整个页面信息的多样化和逻辑的复杂度会高很多。基于这样的背景,咱们在 2020 年做了容器化架构的设计和降级。容器化架构降级次要分为两个阶段,2020 年做了跨端对立的客户端的框架,2021 年做了容器动态化相干的能力,进一步晋升研发效率。咱们打算在前后端各个平台,包含经营平台、算法平台等各方面去欠缺,包含低代码的开发工具,把这个零碎做得更好用更高效。

在 1.0 阶段,咱们次要为了反对业务的降级,实现两端对立的容器框架,能够把所有业务都出现在整个框架下面,同时具备一些根本的规范,比方协定层的协定,还有整个模块容器运行的状态。基于这个事件驱动的模型,2.0 阶段咱们做了模块化,再之后咱们减少了动态化能力,进一步放慢交付效率和升高研发老本。3.0 阶段咱们去欠缺前后端各零碎。

回顾整个我的项目,咱们在复盘的时候总结了两个教训。一是要做取舍,业内也有很多现成的计划能够思考,但并不是每一个都能够拿过去用,所以做技术取舍十分重要。要联合本人团队的能力和指标来做取舍,并不是越简单越好。二是咱们要继续去做架构的降级,要看久远些,咱们的指标是继续推动业务的增长。咱们整个首页反对的业务线有 10 多个,上线之后一年多的工夫里迭代了 100 屡次,放弃了极高的稳定性,同时团队的研发效率晋升 30%,技术改造获得了很好的成果。

将来瞻望

最初介绍一下将来的瞻望,一是原生 SDK 能够做的工作,一直晋升稳定性,升高解体率和异样率,同时逻辑动态化上还有很多能够做的工作。二是欠缺工具箱,比方 IDE、数据可视化等。三是建设生产力平台,让搭建平台更加简略易用,同时要进步零碎自动化能力。

(本文作者:秦阳)

本文系哈啰技术团队出品,未经许可,不得进行商业性转载或者应用。非商业目标转载或应用本文内容,敬请注明“内容转载自哈啰技术团队”。

退出移动版