已开源!分发业务看过来【跨端动态模板引擎】
先祭出项目地址:https://github.com/alibaba/GaiaX
前言
优酷客户端是一个多平台【Phone、Pad、OTT、MacPC】的文娱生态综合体,为了降低多端产品迭代的开发成本,并提供给用户高性能、一致的产品体验,优酷技术团队在 19 年底启动了跨平台动态模板引擎技术方案的攻坚。
作为内容分发的主体,优酷客户端在产品展现层的主要特点是组件设计的规范化和卡片化。优酷动态模板引擎在问题定义上将组件作为了我们的问题空间模型,不仅很好的规避了如 Weex、React Native 等技术方案的复杂度和工程量,让我们可以快速实验及工程化。其次也在根本上让技术方案脱离 JS Bridge 的老路,保证了端侧的高性能。
概述
组件化在目前的移动端来说是非常常见的组件 UI 形态,在优酷客户端的分发场景中,组件则更多的承载了影剧综漫等内容的信息呈现。
当然,组件本身可以通过组合或嵌套来形成更加复杂的展现模式,但从原子化角度来讲,作为单一元素来看,组件有着非常强的结构化特征,抽象后其逻辑构成如下:
1.视觉元素:控件,图片、文本、富文本等
2.布局:视觉元素的位置控制信息及元素绘制样式信息,如坐标及字体、字号等
3.数据:要真实表达给用户的有意义的信息,如影剧综漫的名称、演职员、封面海报等
4.事件:对用户交互的反馈及逻辑响应,如点按钮收藏、预约、关注等
所有的原子化组件都可以抽象为上述的元数据,那如何把这套数据结构进行有机组合形成模板,并在多端场景按照同样的行为表现进行渲染,是本篇文章要详细进行阐述的内容。
什么是模板
在概述中介绍到,我们可以将原子化的组件抽象为元素、布局、数据、事件四类核心信息,其中元素信息,我们通过 JSON 数据结构进行组织,来描述组件中的元素构成及层级关系;布局信息中布局关系通过符合 css3 规范的 flexbox 盒模型进行描述,样式信息则通过标准化的 css 来进行描述;数据模型引入了 XPath 的理念,由于组件元素中最终呈现的数据往往来自云端下发的 JSON 数据,因此,这部分要解决的是如何将组件中文本的 text 属性与云端 JSON 数据中某个层级的 data 实现动态绑定,类似于 root.path.router.title; 至此,通过将上述数据结构整体组合,打包后形成的一个物理文件,我们称之为模板。 当任一客户端完整实现了对这个模板文件的解析与渲染,便可完成组件的绘制工作,从而实现跨端。
优酷动态模板引擎核心实现方案
优酷动态模板引擎是由优酷技术团队自研的,提供对上述模板文件进行跨端标准化解析、构建、渲染的客户端技术方案。由于优酷内容分发场景对用户体验和技术性能有极其苛刻的要求,因此,我们制定的所有技术方案的最高前提是性能第一。
架构设计
动态模板引擎在优酷内部代号为 GaiaX,按照分层设计理念共分为 4 层。基础依赖层坚持最小依赖原则,要重点说明的是,为了保证模板布局计算的高性能,我们引入了由 RUST 编写的 StretchKit 高性能布局计算引擎[https://github.com/vislyhq/stretch],其具备跨端、较小的包体积(170K)、计算性能卓越等特点;核心渲染层构成模板引擎的渲染内核,解决模板文件解析、虚拟节点树构建、布局计算、表达式构建解析等核心逻辑;模板中心及模板服务层则更面向业务,与优酷业务架构进行结合实现对现有能力的复用,避免重复造轮子,并向上层业务提供标准化模板渲染及接入服务。
总线设计
对于动态模板引擎来说,输入结构化的模板文件,经过文件 IO、数据解析、虚拟节点树构建、布局计算、表达式运算、渲染树构建到真实视图树组成了完整的总线链路。
核心实现
虚拟节点树
虚拟节点是链接模板文件,生成布局,绑定样式,以及最后渲染 view 的核心模块,整个链路是属于线程安全,可以在在线程进行操作和布局,在生成 view 的时候回到主线程,可以为后续的预渲染和性能优化提供可靠的保障。
下图是描述 index.json 通过 GaiaNode 和视图 View 的对应关系:
Node 作为基础的虚拟节点,负责 CSS 中 Style 信息生成客户端样式属性,以及 CSS 布局信息通过 StretchKit 生成的 frame 布局信息,同时获取父 node,以及和子 node 数组的对应关系。
Node 和 View 的关系是一一对应的,Node 通过 creatView 的方式创建不同的 view 视图,以及 renderView 的方式将样式和 frame 一次性赋值给 view,减少重复的赋值操作。
在此基础上根据模板中的视图 type 衍生出 rootNode,viewNode,imageNode,以及 textNode。
性能保障
StretchKit 库的优势
选中 Stretch 看中的就是其有着极好的性能表现和较高的内存使用率,而这些都是 Rust 语言特性所带来的。Rust 速度惊人且内存利用率极高,标准 Rust 性能与标准 C++性能不相上下,某些场景下效率甚至高于 C++。由于没有运行时和垃圾回收,它能够胜任对性能要求特别高的场景。
AST 层级极简
AST 即虚拟节点树是根据模板文件构建的逻辑树,其层级结构的合理性完全受制于模板创建者对 flexbox 布局的熟悉程度,为了提高整体技术方案的性能下线,动态模板引擎在进行虚拟节点树构建过程中,会主动进行层级优化和拍平,从而减少不必要的元素冗余关系,提升渲染性能。
线程减负
通过对虚拟节点树进行 DIFF 运算,当真实存在数据改变时才提交更新处理
减少线程池线程数,避免不必要的并发线程间的资源开销及抢夺
对数据遍历、JSON 解析赋值、布局计算等处理进行异步化,保证对于主线程非必要不提交
关键数据
技术方案横向对比
性能表现
线上效果
优酷动态模板引擎业务赋能
目前在优酷 15+业务团队中,均接入使用了动态模板引擎作为跨端提效技术方案;经过自 2020 年起一整年业务应用,从实际效果来看,对于多端组件开发整体研发效率提升可达 30%左右,单组件研发人力投入可由 0.5-1 人日下降至 0.25-0.5 人日。
项目开源
动态模板引擎在优酷业务场景上线后,无论是线上的用户体验、还是研发端的效能度量上都有比较良好的表现。从整个端侧开源社区来看,面向组件级的跨端动态化方案还是比较少的,因此,优酷技术团队在 2021 年 10 月决策将方案进行开源,一方面无论是发现 issue 还是贡献代码,希望通过社区的力量对技术方案实现持续迭代演进,将其打造为功能更加强大的有社区影响力的产品。另外,也希望成熟稳定的技术能力可以帮助更多的个人开发者及中小技术团队,解决客户端日常开发中的痛点问题,实现多赢。
开源计划
项目空间
开源协议:项目遵循 Apache2.0 协议
总结与展望
优酷动态模板引擎在优酷整体业务架构中,已经作为分发场基础能力被各业务广泛使用。由于模板 DSL 是前端技术栈范畴,对于客户端同学来说有一定的学习成本,因此,技术团队在引擎技术能力稳定后的主要研发方向是为使用者提供可视化、搭建化的 LowCodeIDE 平台能力。目前,该能力也已经交付到各技术团队中,从实际效果来看,对降低模板搭建成本非常有效。在动态模板引擎的开源项目中,IDE 本身也进行了同步输出,广大社区开发者可以直接使用平台进行模板搭建。
随着技术方案的开源,团队会根据社区的反馈将开发者关注的问题和能力尽快进行实现,同时,在业务场景孵化的一些新特性,也会实时向社区推出,让更多的开发者受益。
优酷技术团队目前在阿里巴巴开源社区已经开源上线了不少技术方案,后续还将推出更多的能力,也希望广大技术爱好者关注我们,关注优酷端侧技术的发展。
版权声明: 本文为 InfoQ 作者【阿里巴巴文娱技术】的原创文章。
原文链接:【http://xie.infoq.cn/article/f6ea29a392883ca0daa4ae77e】。文章转载请联系作者。
评论