大屏小程序探索实践 | Cube 技术解读
简介: 支付宝客户端有极强的动态化诉求,不论 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/1000354383/
本文为阿里云原创内容,未经允许不得转载。
大屏小程序探索实践 | Cube 技术解读的更多相关文章
- Cube 技术解读 | Cube 小程序技术详解
本文为<Cube 技术解读>系列第三篇文章,之前上线的<支付宝新一代动态化技术架构与选型综述>与<Cube卡片技术栈解读>欢迎大家回顾. 魔方卡片(Cube)已在「 ...
- 【微信小程序项目实践总结】30分钟从陌生到熟悉 web app 、native app、hybrid app比较 30分钟ES6从陌生到熟悉 【原创】浅谈内存泄露 HTML5 五子棋 - JS/Canvas 游戏 meta 详解,html5 meta 标签日常设置 C#中回滚TransactionScope的使用方法和原理
[微信小程序项目实践总结]30分钟从陌生到熟悉 前言 我们之前对小程序做了基本学习: 1. 微信小程序开发07-列表页面怎么做 2. 微信小程序开发06-一个业务页面的完成 3. 微信小程序开发05- ...
- 京东小程序接入ARVR的技术方案和性能调优
作者:京东零售 戴旭 京东小程序是一个开放技术平台,正在被越来越多的头部品牌选择,用于站内私域流量的营销和运营.诸如各种日化.奢侈品等品牌对ARVR有较多的诉求,希望京东小程序引擎提供一些底层能力,叠 ...
- 小程序webview实践
小程序webview实践 -- 张所勇 大家好,我是转转开放业务部前端负责人张所勇,今天主要来跟大家分享小程序webview方面的问题,但我并不会讲小程序的webview原理,而我主要想讲的是小程序内 ...
- 微信小程序开发实践
目录 项目是否适合移植到小程序上? 概要介绍 实践得到的经验 规则 小程序不支持的 新特性 小窍门 会话管理 进阶 项目是否适合移植到小程序上? 小程序由于微信提供了一些组件,在微信中的一些体验确实不 ...
- 【微信小程序项目实践总结】30分钟从陌生到熟悉
前言 我们之前对小程序做了基本学习: 1. 微信小程序开发07-列表页面怎么做 2. 微信小程序开发06-一个业务页面的完成 3. 微信小程序开发05-日历组件的实现 4. 微信小程序开发04-打造自 ...
- 【小程序】微信小程序开发实践
帐号相关流程 注册范围 企业 政府 媒体 其他组织 换句话讲就是不让个人开发者注册. :) 填写企业信息 不能使用和之前的公众号账户相同的邮箱,也就是说小程序是和微信公众号一个层级的. 填写公司机构信 ...
- appium+java(五)微信小程序自动化测试实践
前言: 上一篇<appium+java(四)微信公众号自动化测试实践>中,尝试使用appium实现微信公众号自动化测试,接着尝试小程序自动化,以学院小程序为例 准备工作 1.java-cl ...
- 大学课后答案微信小程序项目实践(1)
叨逼叨 还记得以前小编上大学那会苦于课后习题没有答案...到了考试....就像下面这个图一样- 现在,那些同样在纠结于书本后的答案太遥远的同学们,要告诉你们一个好消息,个人历时两周作业的时间开发的小程 ...
- Java小程序—录屏小程序(下半场)
下半场. 上半场,我们我们写了录屏的程序,那么下半场我们的任务是写一个播放器. 设计思路:播放器的思路就是将图片放在一个JScrollPane中顺序播放,所以还是得使用swing组件,并且仍然要使用线 ...
随机推荐
- 基于python的环境噪声监测报警系统实例解析
一 系统简介 1.简介 该系统可以实时显示噪声量大小,并进行一段时间的噪声统计. 2.特性 实现噪声值的统计 实现了噪声显示 完整的主题和样式控制 多线程的运行模式 二 源码解析 1.串口db值获取: ...
- String.equals(Object anObject)方法
首先注意,equals()方法接受的是Object类型的对象,并不一定是String类型. public boolean equals(Object anObject) { //两个对象地址是否一样, ...
- 3D渲染慢,直接买显卡还是用云渲染更划算?
3D渲染对建筑师和设计师来说并不陌生,3D渲染的过程中出现渲染卡顿.特殊材质难以渲染,或者本地配置不足.本地渲染资源不够时,常常会影响工作效率.本文比较了3D渲染时,为提高工作效率,买显卡还是用云渲染 ...
- Linux输入输出
1.重定向概述 1.什么是重定向 将原本要输出到屏幕的数据信息,重新定向到某个指定的文件中.比如:每天凌晨定时备份数据,希望将备份数据的结果保存到某个文件中. 这样第二天通过查看文件的内容就知道昨天备 ...
- drf(初始drf,restfull规范 ,CBV、APIView、Request源码)
一 web开发模式 # 前后端混合开发(前后端不分离):通过模版语法,在服务器上处理好html的内容(组合字符串),返回给浏览器一堆字符串(字符串封装到respons对象里),浏览器在渲染 # 前后端 ...
- HTML(表格、列表、表单)
表格 表格的主要作用 1.表格主要用于显示.展示数据,因为它可以让数据显示的非常的规整,可读性非常好.特别是后台展示数据的时候,能够熟练运用表格就显得很重要.一个清爽简约的表格能够把繁杂的数据表现得很 ...
- 一文搞懂idea中的根目录和路径(以Mybatis为例)
一文搞懂idea中的根目录和路径(以Mybatis为例) 在 IntelliJ IDEA 中,项目结构和组织比较灵活,允许用户根据项目需求进行定制. 1.根目录概念: 1.1 项目根目录(Projec ...
- 基于pytorch的图像训练识别
一.准备数据集 分为测试集和训练集,文件如下排放 二.开始识别 数据集准备好后,即可导入到模型开始训练,运行下列代码 import time from torch.utils.tensorboard ...
- AXI4从机总线分析验证之读取寄存器值
AXI4从机总线分析验证之读取寄存器值 1.实验目的 利用前面所学的AXI4总线协议的理论分析,验证如何将一个PL的输入信号通过AXI发送到PS端.大致思路就是取一个按键,信号接入自建的AXI4的IP ...
- reinterpret_cast 和 static_cast 的区别
安全性: static_cast 是一个安全的类型转换,它只能转换具有继承关系或密切相关的类型,并且在编译时进行类型检查. reinterpret_cast 是一个不安全的类型转换,它可以将任何类型的 ...