本文为《Cube 技术解读》系列第三篇文章,之前上线的《支付宝新一代动态化技术架构与选型综述》《Cube卡片技术栈解读》欢迎大家回顾。

魔方卡片(Cube)已在「支付宝」App 中被广泛应用,同时,现已支持在 mPaaS 侧对外商业化输出,欢迎广大开发者登录 mPaaS 控制台体验及使用。

而 Cube 小程序则是 Cube 技术除了魔方卡片(Cube)外的另外一种形态,将主要应用与智能电视、POS 机以及其他 IoT 领域,目前还在研发打磨中,欢迎广大开发者交流探讨。

小程序作为动态化或者跨端开发的一种技术栈,在业界成为事实标准。Cube 作为一种轻量级小程序技术栈,具有体积小、启动快、内存占用低等特点,也比较适合“即用即走”的小程序场景。

以下将重点介绍 Cube 小程序技术栈与技术演进实践(若无特殊说明,所有的数据和图表都是针对小程序)。

渲染小程序

模块组成

小程序视角,Cube 渲染引擎主要由以下模块组成:

  • Components:主要是小程序规范里的组件;

  • Layout:支持 Inline,Block,Flex,Inline-Block,Inline-Flex 等多种布局方式,还包括文本分词,断行等计算;

  • Style:支持样式解析,样式匹配,样式继承,伪类和伪元素等多种选择器;

  • Rendering:管理渲染相关 Render Tree,图片资源请求调度等;

  • Animation:JS 和 CSS 动画实现;

  • JS Bridge:和 JS 引擎桥接;

  • JS Engine:目前支持 V8,JSC,QuickJS;其中 Android 下支持 V8,QuickJS;

  • Compositor:用于动画和图层的合成器(开发中)。

线程模型

Cube 小程序技术栈内部有这么几个线程:Bridge,Layout,Render,Paint,UI 等。

  • Bridge 线程:执行 JS;与 AppX 桥接的类 DOM 的 JSAPI;处理 JS 相关事件;

  • Layout 线程:布局计算;样式计算与匹配;维护 Layout Tree;

  • Render 线程:维护 Render Tree;绑定数据;分层;

  • Paint 线程:生成绘制命令;

  • UI 线程:平台事件分发;UI 布局。

小结:

  • 并行布局,异步绘制:这里的并行是指 JS 执行,Layout 布局 以及 Render 三者完全并行处理。由于 Layout 和 Render,Paint 等不在一个线程,因此是异步绘制;

  • 多个线程协同工作,有点像 CPU 的 5 级流水线。

值得注意得是:Web 渲染引擎有个特点就是和 Node 相关的 DOM 操作必须和 JS 在一个线程。这就导致解析 HTML,布局,样式计算,DOM,JS (包括垃圾回收)都在一个线程里。带来的后果就是只有解析完文档才能看到 UI 效果,这也是 Web 渲染小程序白屏时间较长的一个原因。

Cube 小程序技术栈,将“DOM操作” 和 JS 执行解耦。因此 JS 的 GC 不会影响 UI 呈现。这种实现对于加快小程序启动非常有帮助。由于布局计算和 JS 执行也解开耦合,因此一般不会由于 JS 执行阻塞 UI 交互。

Cube 小程序技术栈的特点

  • 体积小,启动快:主 so 只有 2.8 MB(如果包括 Ariver,AppX,InsideSDK,整体小程序技术栈最小是 5.7MB)。另外可以享受到 OS 的红利(包括 UI 的初始化和缓存);

  • 高性能:接近于原生体验;

  • 内存占用小:小程序技术栈初始化后(包括 Inside SDK,Cube,AppX),大约只需要 7.5 MB;

  • 支持 Android,iOS 双端。

与 Web 引擎对比

下面仅仅针对小程序场景与 Web 引擎对比:

技术演进

  • 让小程序业务低成本适配 Cube 渲染小程序,需要做三方面的工作:

  • 拥抱 Web 技术,补齐前端开发常用的能力:包括 CSS,小程序组件等;

  • 完善相关工具:包括开发,调试,Profile,发布,打包等;

  • 针对 Cube 的架构特点,深入优化,并拉开和 Web 渲染的差异。提供更好的用户体验。

新的流式布局(Flow Layout)

最初 Cube 小程序使用只支持 Flex 布局 Yoga 用于布局计算。后面升级成支持 Block,Flex,Inline-Block等多种布局方式的 Flow Layout。从而解决开发者只能使用 Flex 布局的困扰。目前两个布局引擎 Cube 内部都支持。其中 Flow Layout 主要用在小程序,Yoga 用在卡片。两者能力差异如下:

支持 CSS 样式表

老版本的 Cube 只支持内联样式和简单的 CSS 选择器;然而小程序并没有约束 CSS,因此 Cube 扩充支持 CSS 样式表,样式继承,多种选择器等。从而使得 Web 渲染切换到 Cube 渲染,适配成本大大降低。甚至部分小程序可以做到在小程序 IDE 里基于 Web 渲染开发,然后打包成 Cube 渲染产物在真机上预览。前端同学无需进行过多的修改和适配。

新老 Cube 版本,选择器支持上的差异如下:

注:

  • [1] 老版本 Cube 是指:钱包 10.2.0 以前版本;

  • 新样式能力基本上对标 Web 引擎的样式能力;

  • 新样式能力支持像这种复杂选择器。

div > div.jartto p span.yellow a#t1 {}
.pixel-ratio-2 .web1px::before {}
div:nth-child(2n+1) {}
input[type="button"] {}
#blue,div > div.jartto p span.yellow a#t1 {}

支持自动分词,断行(Inline Text)

最初 Cube 用的是 Android 和 iOS 提供的文本计算和绘制能力。这种技术方案(以下称为平台层 Text)存在3个问题:

  1. 性能问题:特别是 Android 下,利用 Android 平台层的接口实现文本布局计算,导致在文本较多的情况下,布局耗时在渲染整体耗时里占比较高;

  2. 富文本特性:富文本以及许多文本特性支持较麻烦;

  3. 各平台上实现文本效果存在细节差异或者兼容性问题。

针对上述问题,在 Flow Layout 基础上增强支持 Inline Text 布局计算文本。基于 Inline Text 可以较轻松实现以下富文本,图文混排,分词,自动换行等。

1.富文本

2.自动换行和分词

Inline Text 实现前后的文本样式对比如下:

注:

  • 假设原有 Cube 采用平台层接口实现的文本特性称为:平台层 Text;

  • √表示实现细节上不完善或者不完全支持;

  • 在 Inline Text 基础上可以实现功能丰富的富文本组件;

  • 值得一提的是:该实现非常精巧,对于 Cube 包体积只增加了 170KB。具体细节后续文章详细探讨。

文本布局计算耗时对比(文本节点较多场景):

采用 QuickJS 替代 V8

V8 虽然是性能最高的 JS 引擎,但是存在内存占用大,初始化较慢等不足。在 IoT 或者低端设备上这些不足会被放大。因此在这些设备上,Cube 采用 QuickJS 取代 V8。一方面降低内存占用,另外一方面提升初始化性能。

Cube 内部目前适配了多个 JS 引擎,具体如下:

  • 在 Android 移动端上使用 V8 和 JSI

  • iOS 上使用 JSC

  • IoT 等低端设备上使用 QuickJS

另外我们在开源 QuickJS 基础上做了些优化工作。优化的结果大致如下(后续文章将详细介绍):

支持动画和多媒体组件

除了上述基础组件和能力之外,动画和多媒体也是部分小程序不可缺少的。因此我们扩展支持了 Video,Canvas、Lottie,Live Player 等组件支持。并应用于 TV 大屏小程序、小游戏以及直播场景上。

在低端设备上,如何提高动画帧率并且降低内存占用也做了深度的优化。以下是 Video 和 Canvas 组件在小程序中的效果图:

支持多种模式的小程序产物

目前 Cube 支持多种模式的小程序产物:Native,Cube,Shared。

  • Native 模式:对应的是旧的 Cube 渲染小程序模式,不支持 CSS 样式表,只能支持内联样式和有限的几种 CSS 选择器。性能最高,兼容性较低;

  • Cube 模式:在 Native 模式进化而来,支持 CSS 样式表和多种 CSS 选择器。性能良好,支持常用的 CSS 样式和特性(包括样式继承,多种 CSS 选择器);

  • Shared 模式:为了降低 Web 渲染的小程序迁移或者过渡到 Cube 渲染而开发。在同一个小程序产物里既支持 Web 渲染一部分页面又支持 Cube 渲染一部分页面。而且 Cube 渲染的页面支持样式表。这样在性能和兼容性平衡。小程序产物相对于 Web 渲染的小程序,产物体积增加不会超过 10%。

注:如果需要 Web 产物兜底,则 Native 模式 和 Cube 模式的小程序产物,比 Shared 模式大。

研发进展

Cube 小程序在 TV 和 POS 机上和相关团队,一起打磨小程序技术栈(包括渲染引擎,JS 引擎,AppX,Ariver 容器)等。

在 TV 上面临的问题:

  • 内存少:有的设备只有 512MB 内存,长列表滚动容易卡;

  • 需要支持焦点切换;

  • CPU 主频较低:有的只有 1GHz。

短中期目标是用小程序技术栈替代 WeeX 单页。当前进展如下:

  • 小程序启动性能上超过 WeeX 单页(低端设备上优势更明显);

  • 内存占用上,小程序初始化后内存占用小于 10MB,典型小程序整体内存占用在 32MB 左右。

具体细节后续文章详细总结。

在 POS 机上面临的问题:

在 POS 机上跑点餐小程序,主要有面临以下问题:

  • 内存少:部分设备只有 512MB 内存,容易出现卡死和 OOM;

  • CPU 核心少:部分 CPU 只有双核(硬件性能大约是主流手机的 1/5);

  • 长列表滚动卡。

短中期目标是用小程序技术栈替代 Flutter 开发的 App。当前进展如下:

  • 小程序首屏启动性能提升了 30%+;

  • 小程序重点的交互场景的页面,比如:购物车,商品详情页等,都已接近 Flutter App;

  • 首页滚动帧率达到 50,用户已经难以感知和 Flutter 的差异(Flutter 帧率是 60);

  • 小程序内存占用下降了 30%(本地测试已无卡死和 OOM)。

该场景主要是文本节点较多的长列表。采用了非常多的优化方法,后续文章详细总结介绍。

总结

为了适配小程序,Cube 渲染引擎在布局计算、样式能力、组件支持,还有开发工具等在小伙伴一起努力下取得了较大的进展。同时在低端设备(比如:IoT 设备)或者性能敏感场景,Cube 小程序性能优化,降低内存占用也取得了不错的效果。

而未来面对多种多样的 IoT 设备,还需要加速技术演进以支持更多的场景。欢迎大家一起来交流讨论。

本文转自公众号「阿里巴巴移动技术」,作者:曾维宏(恒实)


最新文章

  1. << CocoaPods安装和使用教程 >>github code4app以及cocoachina 苹果官方文档
  2. SoapUI中如何传递cookie
  3. Java堆
  4. git克隆项目到一个非空目录
  5. Graylog2+mongdb+rsyslog中央日志服务器对syslog的web管理--转载
  6. Nginx + Tomcat 动静分离实现负载均衡(转)
  7. javaweb学习总结十一(JAXP对XML文档进行DOM解析)
  8. C语言获取网页源代码的学习所得
  9. 【nodemailer】之 work with mustache
  10. MYSQL创建用户Unknown column 'plugin' in 'mysql.user'的解决方法
  11. oracle中 merge into 的用法
  12. 文字太多?控件太小?试试 TextView 的新特性 Autosizeing 吧!
  13. WebServeice 动态代理类
  14. Bytom Java版本离线签名
  15. 1 virtual
  16. 2018.12.31 bzoj3992: [SDOI2015]序列统计(生成函数+ntt+快速幂)
  17. Mina使用总结(四)传输对象ObjectSerializationCodecFactory
  18. Python概念-迭代器的__iter__和__next__
  19. Hello Vizhub
  20. 开始使用 Vuejs 2.0 ---简单总结1

热门文章

  1. Linux 设置时区
  2. rust常用技巧
  3. c3p0的使用步骤
  4. java多线程并发编程中的锁
  5. 沉淀vue相关知识(主要还是个人积累用)
  6. python3约瑟夫环问题
  7. shell脚本 检查mysql节点数据一致性
  8. 【dva】model中effects函数的解析
  9. 如何基于 Docker 快速搭建 Springboot + Mysql + Redis 项目
  10. bjdctf_2020_babystack2