简介: 支付宝客户端有极强的动态化诉求,不管 iOS 还是 Android 平台,从新散发软件包从工夫上,效率上难以满足产品经营的要求,因而客户端动态化技术应运而生。 Cube 起源于 Native 页面的动态化诉求,随着小程序的呈现,Cube 融入了支付宝小程序技术栈,产品状态为轻量级的支付宝小程序解决方案(绝对于应用浏览器作为外围的 Web小程序)。作为一个轻量级引擎,Cube 小程序具备体积小、启动快、内存占用低的特点。而在IOT畛域,因Cube以上的劣势,于是衍生出了适宜大屏的小程序技术栈。所谓大屏小程序,是以 Cube 小程序技术栈 为载体,运行在智能电视或智能机顶盒等设施上的一种小程序状态。这些设施的次要特点是:以 Android 零碎为主,零碎版本广泛较低,有些设施仍然停留在 Android 4.2,Android 4.4 以下设施占比在40%+;内存低,512MB 以下的设施占比超过 20%,1GB 以下的设施占比超过 60%;CPU 主频低,双核占比在 20% 左右,有的只有 1.5GHz;和手机设施相比拟,按手机淘宝的设施评分体系为参照的话,全部都是低端设施。正是因为这些智能电视或智能机顶盒人造存在的硬件上的瓶颈,且运行在这些智能电视或智能机顶盒上的Android 应用程序在版本公布上受行业广电监管以及硬件厂商的限度诸多,每年只有几次的版本公布迭代窗口。所以亟需一种更小、更快、更省的动态化技术栈来解决用户设施降级周期长,客户端版本长尾问题。而 Cube 小程序技术栈,从设计之初就具备更小、更快、更省的特点,因而成为智能电视或智能机顶盒(以下简称为 OTT设施的不二抉择。对于 Cube 渲染引擎来说,在支付宝钱包中,面对的是手机端的场景,而在OTT上,面对的是一个全新的场景,既须要解决 OTT 设施的性能问题,也须要更正当的焦点引擎能力的反对。焦点引擎何为焦点引擎?下面提到了何为大屏小程序以及大屏小程序运行的 OTT 设施,而这些 OTT 设施的交互方式,就是通过遥控器来操作,这一点和触控设施齐全不同。遥控器通过 Android 零碎的按键零碎,进行事件散发,来实现应用程序的交互,那么这里就不得不提到咱们的焦点引擎,也就是 FocusEngine 了。所谓 FocusEngine,理论包含几大部分:FocusNode (焦点 View )、FocusTree (焦点树)、FocusFinder (焦点查找器)、FocusState (焦点状态)、FocusEffect(焦点成果)。 而原有的 Cube 小程序技术栈不具备FocusEngine 的能力,也就是说渲染引擎中短少最初一棵树 FocusTree,更没有焦点查找器、焦点状态以及焦点成果的反对。对于Cube 小程序渲染引擎中 LayoutTree,RenderTree,LayerTree,此处不再进行额定赘述,具体理解可参见之前文章介绍《Cube 渲染设计的前世今生》中常见术语和数据模型的介绍。实现细节下面咱们提到 FocusEngine 蕴含的几个次要局部,上面咱们来看看 Cube 小程序渲染引擎中的无名英雄------ Focus 的实现。FocusNode (焦点 View )FocusNode 是用于获取遥控器按键事件的对象,也就是说当小程序的 AXML 中一个 view 节点具备了focusable 属性时,那么在 Cube 渲染引擎中会映射成一个 FocusNode 节点,且会进行实体化。该节点具备被动获取焦点 requestFocus 和被动革除焦点 clearFocus 的能力,同时也能够监听 focus 的变动,可接管到 onFocusChange 的回调 onFocus 和 onBlur 事件告诉<view id="focus-control" class="button" focusable="true" onFocus="handleFocus"
onBlur="handleBlur">

doRequestFocus() {
my.createSelectorQuery().select('#focus-control').node().exec(function(ret) {

const ref = ret && ret[0];ref.requestFocus();

})
}FocusTree (焦点树)FocusTree 是与 Cube 渲染引擎中的 LayerTree 独立开的,一棵独自的实体节点的 Tree,它次要用于保护 LayerTree 中可聚焦 FocusNode 之间的父子关系。FocusTree 临时无奈通过独自的工具查看这棵树的构造,但挂在树上的 FocusNode 可通过 DevTools 的 Elements 或 Android 的 LayoutInspector 查看,后续会思考反对进行独立树的 dump 后导出不便查看。焦点树结构示例如下: 

FocusFinder (焦点查找器)FocusFinder 是负责焦点搜寻逻辑的外围查找器,外部保护着用于从以后具备焦点的 FocusNode 中查找给定方向上的下一个可聚焦 FocusNode 的算法(PS:这里的方向指的是遥控器操作的上下左右)。在 Cube 的渲染引擎中,无论是 Layout、Render pipline,还是 Tree,代码均采纳 C++ 来实现,而FocusFinder 的算法实现亦是如此。咱们在 FocusFinder 的实现上,以 Android 的 FocusFinder 实现为底本,实现了适宜 Cube 渲染引擎的焦点查找算法,去除了 Android 自身的 descendant focusability  反对,采纳默认FOCUS_AFTER_DESCENDANTS 的查找策略,且基于外部 FocusNode 的管理机制,不再额定提供UserSpecifiedFocusNode 的反对,并反对了五种优先级查找策略,别离为CENTER_FIRST(两头对齐优先)、LEFT_FIRST(左对齐优先)、RIGHT_FIRST(右对齐优先)、TOP_FIRST(顶对齐优先)、BOTTOM_FIRST(底对齐优先)。焦点查找策略举例说明如下:

如上所示,以后获取焦点的 FocusNode 为 A,而 FocusNode B 和 FocusNode C 在程度方向上与 Current Focus Node A 的 Rect 存在交加,因而在外部咱们会通过带权重比的间隔判断;FocusNode E,在垂直方向上与Current Focus Node A 的 Rect 有交加,而程度方向上没有,所以更适宜作为 FOCUS_UP 的焦点查找,而不是FOCUS_LEFT 的查找;而 FocusNode B 和 FocusNode D,依照 Cube 的渲染引擎的规定,在程度方向上是容许跨列挪动焦点的而垂直方向是不容许跨列挪动焦点的 且 FocusNode E 会作为 FOCUS_UP 的优先选择, 因而,此时进行 FOCUS_LEFT 的时候,会优先选择 FocusNode B。FocusState (焦点状态)FocusState 是负责保护 FocusNode 节点焦点状态的管理者,外部保护 FocusNode 节点的焦点状态,因为在 AXML 下,当一个 View 节点取得 focusable 属性时,那么此时该节点会被标记成 FocusNode 节点。当Android 零碎按键散发时,FocusFinder 接管到查找的命令,会从 FocusTree 中进行 FocusNode 的查找,当找到最合适的 FocusNode 节点时,那么此时该 FocusNode 须要标记本人的 FocusState 为 focused 状态,与此同时,假如外部的 child node 没有 FocusNode,但有叶子节点 text 或 image,那么此时会标记 text 或 image 节点为 selected 状态。FocusEffect (焦点成果)FocusEffect 次要用来示意不同的节点对应的 FocusState 的焦点成果,在前端开发者视角下,次要通过 CSS 的伪类 :focus 来实现,如下代码片段:.button {
margin-top: 30rpx;
margin-left: 15rpx;
width: 450rpx;
height: 200rpx;
border: 2rpx red solid;
}

.button:focus {
border: 2rpx blue solid;
}如下图所示,高亮的 Item 所在的节点为以后取得焦点的 FocusNode:

上面看下在 OTT 设施上 Cube 小程序的根底性能数据:(以淘宝特价版小程序为例)

因优化环节波及到整体小程序技术栈,所以这里简略提一下小程序基础设施中的几大部分,其中包含:容器,前端框架,Cube 渲染引擎,脚本引擎。次要性能优化伎俩包含但不限于以下内容:包大小:移除 OTT 设施不须要的能力模块,移除 AntUI、平安数据库、permission 管控模块,共享apk 宿主内 so。脚本引擎:在支付宝钱包挪动端上应用 JSC/V8 作为 JS 代码的执行引擎,IOT 设施上应用的是 QuickJS。内存占用:动态区块优化;JNI Global Reference 优化;Activity Context 上下文,虚拟机和 Native 的解耦,避免 Context 被 Native 持有,造成内存泄露;Native 中渲染树相干内存优化,内存泄露检测解决。启动性能:虚拟机优化方面,应用 Class Verify 克制 + GC 克制;优化 Android InvocationHandler 动静代理在中低端设施耗时问题;小程序产物 Bytecode 能力反对,缩小小程序产物在脚本引擎下 Parse 和 AST 的阶段耗时,间接执行Bytecode。下面咱们介绍完了和 FocusEngine 相干的实现细节,置信大家对于 FocusEngine 所蕴含的几个次要局部有了初步的意识和理解。通过上述对于 FocusNode 节点以及 FocusEffect 伪类的代码片段,不难看出,只有应用了 Cube 小程序技术栈,那么开发一个大屏小程序,和开发一个一般的支付宝小程序差异性是微不足道的。除了开发方式和一般支付宝小程序齐全无二之外,在调试工具上也是能够应用 Chrome DevTools 来进行编辑和批改相应的可 Focus 的 DOM 节点的,如下图所示:

从拥抱 Native 开发,到拥抱动态化小程序技术栈开发,即解决了碎片化设施下的长尾瓶颈问题,又是产品技术的架构降级。在 CIBN 酷喵影视下,咱们和业务方一道进行了大胆的翻新和摸索,最终实现了多种 Cube 小程序的产品状态。其中包含用于双十一战斗的直播间半屏小程序、用于桌面首页大作业的 Tab 小程序、用于搜寻广告下的嵌入式小程序、以及用于业务经营的全屏小程序,成果别离如下:

对于渲染引擎自身的思考,将来会进一步打磨整体的渲染链路,在性能上晋升 Cube 小程序的启动性能。家喻户晓,解释性语言每次运行时都须要通过解释器对程序进行动静解释和执行。而这个过程少不了从 Parse 到AST,再从 AST 到 Bytecode 的过程,将来会进一步缩小 Parse 和 AST 的过程,能充分发挥脚本引擎对Bytecode 的反对,晋升启动性能。另外,也会逐步缩小对 Platform 层的依赖,使 Platform 层更轻量化,充沛升高 Cube 渲染零碎和平台自身的渲染零碎的耦合,更好的欠缺晋升渲染自身的能力。在业务场景摸索上,将来会与更多的二三方进行单干,无论是大屏端的 App,还是桌面 launcher,帮忙他们解决版本长尾效应和业务动态性问题,当然也会有更多的场景的反对,譬如小游戏,3D等。如果你须要一种更小、更快、更省的动态化渲染技术栈,且具备更好的开发体验和行业共识,那么 Cube 兴许是一个不错的抉择。原文链接:https://click.aliyun.com/m/10...本文为阿里云原创内容,未经容许不得转载。