Cube 技术解读 | 详解「支付宝」全新的卡片技术栈

简介: 魔方卡片(Cube),让 App 首页实现敏捷更新。

封面图1109.png

CodeHub#7 正式落幕,来自蚂蚁集团的技术专家「京君」与掘金社区的开发者们分享了「支付宝」全新的卡片技术栈——魔方卡片(Cube)。

京君围绕 Cube 技术的架构逻辑,阐述其渲染和生产过程,并指导开发者完成初阶的技术调试。

动态卡片的背景

从 Windows 时代开始,应用程序图标就成了用户(流量)的主入口,并且一直持续到移动端时代。图标即入口的方式,缺点是不直观,最少需要一次点击后才能接触到想要的信息。在此背景下,iOS系统和部分Android系统实现了把内容和服务前置的卡片,如下图所示:

卡片.jpg

此外,鸿蒙系统也提出了类似的卡片场景,作为某种流量入口。实际上,在应用内部的卡片作为内容展示以及服务入口的场景则更为普遍,比如支付宝首页和招行银行的理财页面,其中每个小矩形都是一个卡片。对于运营来说,卡片样式和内容可以随时配置,不用等待应用版本升级,也是某种刚需。

魔方卡片(Cube)概要

魔方卡片(Cube)是蚂蚁集团内部自研的一套跨平台动态化卡片解决方案,是服务于应用页面内的区域动态化技术,面向内容运营,帮助产品技术提高开发效率和运营效率。每一个魔方卡片(Cube)独立嵌在原生页面内的一个区域,区域内容通过卡片模版进行展示。

Cube卡片技术解析(对外)-2.png

这里展开讲下高性能。魔方卡片(Cube)追求的是接近native原生体验。我们定义了两个维度:

一个是极致的性能。在Cube小程序能力的基础上,我们去掉了一些复杂的css能力,例如伪类伪元素、inline/block等,同时也对js的能力做了限制(魔方卡片使用quickjs作为脚本引擎)。此外,我们还对quickjs做了一些优化,包括不限于离线atom编译优化,异步gc优化等。我们也引入了wamr作为quickjs的“协处理器”,支持用户使用javascript和assemblyscript混合开发。这样用户可以用assemblyscript一些热点函数或者模块。

另一个维度是极致的内存。在信息瀑布场景无限下拉,魔方卡片的内存增长接近Native卡片。我们对卡片的能力做了比较精细分级,通过在开发时配置,减小运行时的内存消耗。下图展示了一个简单卡片,如图所示魔方卡片的工程目录,以及钱包某个卡片的真实代码和运行效果。

2.png

Cube卡片的生产&工作流程

Cube卡片技术解析(对外)-9.png

  • 研发期
    • 本地开发

魔方卡片(Cube)配套独立的开发工具,支持卡片的编译、日志输出、实时预览等功能,vue作为当前开发模版的dsl语言,支持js、css编辑卡片样式。

    • 卡片管理

卡片本地开发完成后,通过卡片管理后台将卡片编译产物上传发布,可以对卡片进行版本管理,卡片发布后就可以在客户端进行卡片的动态更新。

  • 运行期

为了方便端上业务接入魔方卡片,我们引入了一个魔方卡片容器(CardSDK)的概念。CardSDK把一些和业务层/服务端联系紧密的,且通用能力做了一些封装。例如我们通过CubeCardSdk从服务端拉取卡片和业务数据。此外CardSDK也负责常用的JSAPI、第三方组件的接入。这样魔方卡片能够更专注于卡片产品本身。

核心系统架构

魔方卡片(Cube)的系统架构主要包括JSEngine、CardEngine、RenderEngine和Platform几部分,绝大部分代码都是C++实现。

Cube卡片技术解析(对外)-5.png

  • JSEngine

主要负责卡片js逻辑执行和卡片数据变化监听,从而支持开发者在卡片内部写一些业务逻辑能力实现卡片内容和样式的动态变化。

因为卡片场景对性能要求较高,综合包大小和性能等方面考虑,我们选择了quickjs作为我们的js基础引擎库,同时实现了一个非常小的js响应式框架(JSFM),用来支持卡片内的逻辑代码能力。

  • CardEngine

主要负责卡片数据的解析和绑定、卡片逻辑渲染、构建DOM指令、JSAPI管理、JSBinding、Native事件通信等。

卡片DOM树的初始化构建过程,我们并没有把它放在js运行时,而是在卡片实例初始化链路中直接通过C++进行指令生成和树构建,一方面是为了保持js框架更小更快,另一方面C++的运行效率更高。

  • RenderEngine

后端渲染底座,负责卡片布局计算、样式解析、Layer计算、自绘制组件、同层渲染、光栅化上屏等过程,以及手势、动效等交互效果。

  • Platform

平台相关接口,包括原子view封装、Canvas API、三方组件扩展协议、动画api等。

线程模型和数据模型

线程模型

魔方卡片(Cube)生命周期内的主要线程包括业务线程和引擎线程,业务线程是卡片数据的初始化阶段由业务发起执行,是卡片生命周期的beforeCreate阶段。引擎线程是所有卡片生命周期运行阶段的共有线程,主要包括Bridge线程、Render线程、Paint线程和UI主线程。

  • Bridge线程

js运行时线程,也是Dom节点数据查询和处理线程,因为基于魔方卡片小、快的定位,js逻辑只是卡片一个辅助能力,不具备过于复杂业务逻辑能力,所以Bridge线程相对较轻,并设计为单线程模式。

  • Render线程

渲染相关数据计算线程,包括渲染树构建、节点层级计算、Layer分层绘制计算、手势数据计算以及渲染任务构建,Render过程主要涉及树的递归计算过程,相对渲染过程耗时很短, 设计为单线程模式。

  • Paint线程

绘制线程,执行卡片节点分层绘制及光栅化任务。Paint线程并不是一个固定的线程,根据当前任务模型,Paint线程可能是主线程,也可能是一个线程池里的子线程;在同步渲染模式下,Paint线程直接是主线程;而在异步渲染模式下,通过一个线程池来实现Paint任务的并发渲染,提高渲染效率,例如在列表滑动场景。

  • UI主线程

UI操作主线程,即为目前的平台线程,主要包括手势识别、UI上屏和三方扩展组件的数据更新等。

除了以上涉及的主要线程外,还有埋点和监控相关的playground后台线程,整体优先级比较低。整体的线程模型设计,最大限度减少UI主线程压力,提高卡片并发渲染效率。但目前还有一些不足,包括UI线程切换频繁、Bridge线程越来越重等,后面会继续优化线程模型。

Cube卡片技术解析(对外)-6.png

数据模型

和线程模型对应的数据模型主要包括三棵树:NodeTree、RenderTree、LayerTree,除此之外,还存在一个临时的PaintTree;

  • NodeTree

卡片原始节点树,对应前端的Dom树,引擎会根据NodeTree做样式解析和布局计算;

  • RenderTree

渲染数据树,这是一颗变形树,很多情况下它的树层级结构和NodeTree是一样的,其实当初在设计定义引擎数据模型的时候,我们讨论过到底要不要这棵树,有没有必要存在这样一颗和NodeTree层级一样的树,最终我们还是保留了,原因是这棵树可以比较灵活的调整树关系,如果把卡片分为布局阶段和渲染阶段,那么这颗树就是渲染阶段的源树。

事实证明我们的决定是正确的, 我们后续支持的zindex/static等能力,都是因为这棵树的存在可以在引擎层很好的去支持, 而不用在平台层去模拟实现这种层级变更能力从而导致很有限的场景支持,包括以后我们做渲染快照技术也可以从这颗树去考虑。

  • LayerTree

LayerTree树,顾名思义就是一个分层树,在RenderTree基础上对节点进行分层,同一层的节点在同一个渲染任务管线内做绘制光栅化,不同层之间相互独立,可以并发渲染。

  • PaintTree

PaintTree是一个临时树,其实严格的说是一个拷贝树,是通过RenderTree拷贝一个子树,每次发生渲染时临时生成,当然也会做些节点优化处理,例如被完全盖住的节点会被优化调,避免重复渲染。每一个layer上存在一个PaintTree,通过PaintTree进行节点绘制生成光栅化指令或位图。

Cube卡片技术解析(对外)-7.png

高性能列表渲染

对于列表内使用卡片的场景,主要考虑的是卡顿影响,尤其是中低端机设备。魔方卡片(Cube)支持异步渲染,所以在列表场景下可以很流畅,同时因为支持多线程并发能力,可以多张卡片并发渲染,所以在异步渲染条件下也不会有明显的白屏效果。

Cube卡片技术解析(对外)-8.png

Native技术优化

我们期望卡片服务于页面内区域化内容动态展现和简单业务逻辑,更多的是面向移动端开发者。即使我们使用的卡片DSL语言描述是前端语言,我们也希望能够对CSS的使用做约束、支持有限的CSS能力,但同时也希望尽可能覆盖到一些开发者常用的CSS能力。

所以我们针对CSS能力做了一个专项工作,和前端团队技术同学一起做了魔方卡片(Cube)CSS能力规范,对CSS能力做了约束限制。即便如此,在Native渲染引擎下,想非常好的去支持这些能力,也是有很多困难,包括zindex的支持、overflow等,因此我们也基于一些依赖的平台能力也做了优化处理。

Layer容器

我们引入Layer容器概念,前面介绍数据模型时,提到了LayerTree,每一个Layer节点是一个独立的渲染容器,由平台View作为Layer容器来渲染其他虚拟节点。如果按照常规的做法是一个View对应一个渲染容器,我们使用两个View组合为Layer容器(iOS使用CALayer),将内容层和逻辑层分离,这样做的好处很多,例如layer节点的shadow绘制限制裁剪问题、内容层的画布切割优化等。

3.png

手势改造

手势的优化改造主要为了解决平台系统手势分发能力的限制,不管是Android平台还是iOS平台,系统对手势的分发处理都有一些限制,例如兄弟节点不能分发事件(iOS)、超过父节点区域无法接收事件(影响overflow能力)等,所以需要对手势进行改造。

因为卡片渲染支持三方组件扩展,为了不影响扩展组件的事件响应,我们基于Layer容器接管改造系统手势行为,内部进行容器节点的手势分发管理,而对于存在三方组件混合渲染的场景,Layer容器和三方组件之间的手势分发保持系统行为。

4.png

光栅化

魔方卡片(Cube)渲染过程包括指令渲染和位图渲染两种渲染模式,这两种模式会在不同场景条件下切换,用来优化不同场景下性能,例如帧率和内存。位图渲染在Android上相对比较复杂。默认是用Bitmap作为离线渲染的缓存,缺点是引入一次额外cpu/gpu内存拷贝并且无法充分利用GPU资源,优势是兼容性好。我们尝试过使用textureview作为离线渲染缓冲,发现6.0以下设备存在严重的兼容性问题,而且不同设备之间的稳定性差别巨大。

同时光栅化能力依赖平台系统的Canvas API,有些高阶方法会涉及硬件加速的限制,包括shadow api以及系统对glRender buffer的限制(Android平台),我们也对大画布场景做了视图切割分段渲染来保证渲染性能。我们同时也在着手用Skia Canvas api替代平台层的Canvas API。

同层渲染

魔方卡片(Cube)把三方组件当作独立一层layer单独进行数据更新,可以非常方便高效的接入扩展的三方组件。基于系统的UI能力,使扩展组件在卡片内天生统一渲染。同时支持组件在不同卡片上的复用。在实际的业务场景中,同层渲染也带来了很多额外的问题。诸如地图/视频/动画等组件,一般会伴随着较大的性能内存开销。这些开销对卡片的渲染会有负面影响,尤其在列表滚动时。对于地图/视频组件,我们配合组件提供方case by case的解决问题,并且试图在卡片上线时设置卡点。对于动画组件,Cube持续的在扩展属性动画/帧动画能力,并且内置canvas能力。

魔方卡片(Cube)的现状和规划

目前魔方卡片(Cube)已经服务「支付宝」的首页、证券(股票)、卡包、出行等20+的业务场景,日pv超过100亿。在未来相当长的一段时间内,「支付宝」内部的业务场景,将逐步把存量的native卡片和h5卡片Cube化。

因此,我们一方面会持续把开发者体验做好,诸如开发调试工具链条;另一方面我们也将持续的优化基础性能,诸如追求更小的包体积,更低的内存等。

3r45.png

同时,魔方卡片(Cube)Beta 已上线 mPaaS 供广大移动开发者使用,公测期间,登录 mPaaS 控制台,立即赠送十个卡片模版免费使用。> > 点击这里 < <体验魔方卡片。

卡片未来规划的另一个方向是物联网设备(例如RTOS)的应用开发栈。准确说不是魔方卡片,而是卡片和小程序的某种中间形态。

物联网设备的界面一般比较简单,近似卡片;但是又需要多个“卡片”之间的路由能力,更接近于应用的形态。这样一个混合形态既能保留魔方卡片(Cube)在内存/性能/包体积上的优势,又能满足物联网设备应用开发的诉求。

根据我们的调研,大部分RTOS应用开发环境还是停留在传统的C语言,效能和动态性都不理想。因此对于开发者来说,Cube 也许是一个不错的选择。

原文链接
本文为阿里云原创内容,未经允许不得转载。 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/512063.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

庖丁解InnoDB之REDO LOG

简介&#xff1a; 数据库故障恢复机制的前世今生一文中提到&#xff0c;今生磁盘数据库为了在保证数据库的原子性(A, Atomic) 和持久性(D, Durability)的同时&#xff0c;还能以灵活的刷盘策略来充分利用磁盘顺序写的性能&#xff0c;会记录REDO和UNDO日志&#xff0c;即ARIES方…

oracle 取整点的数据,Oracle SQL语句操作数字:取整、四舍五入及格式化

用oracle sql对数字进行操作: 取上取整、向下取整、保留N位小数、四舍五入、数字格式化取整(向下取整)&#xff1a;select floor(5.534) from dual;select trunc(5.534) from dual;上面两种用法都可以对数字5.534向下取整&#xff0c;结果为5.如果要向上取整 &#xff0c;得到结…

Web 自动化神器,批量下载美图,可直接导入使用

‍‍作者 | 小碗汤来源 | 进击云原生今天为大家分享一款前端自动化操作神器: Automa。Automa介绍它是一款 Chrome 插件&#xff0c;即使你不会写代码&#xff0c;也能按照自己的需求&#xff0c;完成一系列自动化操作。利用它&#xff0c;你可以将一些重复性的任务实现自动化、…

RocketMQ 5.0 POP 消费模式探秘

简介&#xff1a; POP Consumer—使客户端无状态&#xff0c;更轻量&#xff01; 作者&#xff1a;凯易&耘田 前言&#xff1a;随着 RocketMQ 5.0 preview 的发布&#xff0c;5.0 的重大特性逐步与大家见面。POP Consumer 作为 5.0 的一大特性&#xff0c;POP 消费模式展现…

oracle排列组合,sql实现排列组合

employe 表中的数据EMPNO ENAME JOB DEPTNO SAL101 实施一部员工1 部门领导 10 1205.775102 实施一部员工2 普通员工 10 1341.174103 实施一部员工3 普通员工 10 1195.74104 实施一部员工4 普通员工 10 1529.176105 实施一部员工5 普通员工 10 1901.084106 实施一部员工6 普通…

【ESSD技术解读-01】 云原生时代,阿里云块存储 ESSD 快照服务如何被企业级数据保护所集成?

简介&#xff1a; 本文描述了阿里云块存储快照服务基于高性能 ESSD 云盘提升快照服务性能&#xff0c;提供轻量、实时的用户体验及揭秘背后的技术原理。依据行业发展及云上数据保护场景&#xff0c;为企业用户及备份厂商提供基于快照高级特性的数据保护的技术方案&#xff0c;满…

一把王者的时间,我就学会了Nginx

作者 | 步尔斯特来源 | CSDN博客Nginx 简介Nginx("engine x")是一个高性能的 HTTP 和反向代理服务器,特点是占有内存少&#xff0c;并发能力强&#xff0c;事实上 nginx 的并发能力确实在同类型的网页服务器中表现较好&#xff0c;中国大陆使用 nginx 网站用户有&…

【ESSD技术解读-02】企业级利器,阿里云 NVMe 盘和共享存储

简介&#xff1a; 当前 NVMe 云盘结合了业界最先进的软硬件技术&#xff0c;在云存储市场&#xff0c;首创性同时实现了 NVMe 协议 共享访问 IO Fencing 技术。它在 ESSD 之上获得了高可靠、高可用、高性能&#xff0c;同时基于 NVMe 协议实现了丰富的企业特性&#xff0c;如…

php数组json函数,php数组转json的函数是什么

php数组转json的函数是json_encode()。json_encode()函数可以对变量进行JSON编码&#xff0c;将其转换为json字符串数据&#xff0c;语法格式“json_encode (value)”。本教程操作环境&#xff1a;windows7系统、PHP7.1版&#xff0c;DELL G3电脑php数组如何转为json&#xff1…

使用友盟+的APM服务实现对移动端APP的性能监控

简介&#xff1a; 对于信息系统服务&#xff0c;一般我们的重点监控对象都是核心的后端服务&#xff0c;通常会采用一些主流的APM(Application Performance Management)框架进行监控、告警、分析。那么对于移动端的APP、小程序的运行时状态如何进行实时监控与分析呢&#xff1f…

首届“中国物联网数据基础设施最佳案例评选”结果出炉

供稿 | 映云科技 出品 | CSDN云计算 随着物联网技术的成熟与普及&#xff0c;如今的世界早已进入万物互联的时代&#xff0c;全球年活跃连接的物联网设备已达数百亿规模 &#xff08;IoT Analytics, 2021&#xff09;。海量物联设备产生的数据&#xff0c;需要通过统一汇聚和…

Serverless 工程实践 | 快速搭建 Kubeless 平台

简介&#xff1a; Kubeless 是基于 Kubernetes 的原生无服务器框架。其允许用户部署少量的代码&#xff08;函数&#xff09;&#xff0c;而无须担心底层架构。 快速搭建 Kubeless 平台 Kubeless 简介 Kubeless 是基于 Kubernetes 的原生无服务器框架。其允许用户部署少量的…

并发编程实践之公平有界阻塞队列实现

简介&#xff1a; JUC 工具包是 JAVA 并发编程的利器。本文讲述在没有 JUC 工具包帮助下&#xff0c;借助原生的 JAVA 同步原语, 如何实现一个公平有界的阻塞队列。希望你也能在文后体会到并发编程的复杂之处&#xff0c;以及 JUC 工具包的强。 作者 | 李新然 来源 | 阿里技术公…

php 什么时候传引用,什么时候在PHP中使用传递引用?

以下内容不适用于对象&#xff0c;因为这里已经说明了。如果计划修改传递的值&#xff0c;则通过引用传递数组和标量值将只会节省内存&#xff0c;因为PHP使用了更改时复制(copy-on-change)策略。例如&#xff1a;# $array will not be copied, because it is not modified.fun…

iOS App 启动优化

简介&#xff1a; 作为程序猿来说&#xff0c;“性能优化”是我们都很熟悉的词&#xff0c;也是我们需要不断努⼒以及持续进⾏的事情&#xff1b;其实优化是⼀个很⼤的课题&#xff0c;因为细分来说的话有⼤⼤⼩⼩⼗⼏种优化⽅向 &#xff0c;但是切忌在实际开发过程中不能盲⽬…

apache1.3 php编译,安装Apache1.3.29 - Linux+Apache+Mysql+PHP典型配置详解_Linux教程_Linux公社-Linux系统门户网站...

2.安装Apache1.3.29。我没有选择安装Apache2.0是我对他还是不放心&#xff0c;因为网上最新公布的apache的漏洞基本上是针对2.0&#xff0c;当然大家可以自己选择安装相应的版本。我这里讲的都是采用DSO动态编译的方法编译Apache.至于有关apache的编译方法&#xff0c;可以参考…

前后端、多语言、跨云部署,全链路追踪到底有多难?

简介&#xff1a; 完整的全链路追踪可以为业务带来三大核心价值&#xff1a;端到端问题诊断&#xff0c;系统间依赖梳理&#xff0c;自定义标记透传。 作者 | 涯海 全链路追踪的价值 链路追踪的价值在于“关联”&#xff0c;终端用户、后端应用、云端组件&#xff08;数据库…

供应商太多,怎么才能高效比价?

本篇文章暨 CSDN《中国 101 计划》系列数字化转型场景之一。 《中国 101 计划——探索企业数字化发展新生态》为 CSDN 联合《新程序员》、GitCode.net 开源代码仓共同策划推出的系列活动&#xff0c;寻访一百零一个数字化转型场景&#xff0c;聚合呈现并开通评选通道&#xff0…

7张图揭晓RocketMQ存储设计的精髓

简介&#xff1a; RocketMQ 作为一款基于磁盘存储的中间件&#xff0c;具有无限积压能力&#xff0c;并提供高吞吐、低延迟的服务能力&#xff0c;其最核心的部分必然是它优雅的存储设计。 存储概述 RocketMQ 存储的文件主要包括 Commitlog 文件、ConsumeQueue 文件、Index 文…

apache php隐藏头信息的方法,apache、php隐藏http头部版本信息的实现方法

1、apache隐藏头部版本信息&#xff0c;编辑httpd.conf文件&#xff0c;找到&#xff1a;ServerTokens OSServerSignature On修改为&#xff1a;ServerTokens ProductOnlyServerSignature Off2、上面的方法是默认情况下安装的Apache&#xff0c;如果是编译安装的&#xff0c;还…