Cube 技術解讀 | Cube 小程式技術詳解
“ 本文為 《 Cube 技術解讀》系列第三篇文章,之前上線的 《支付寶新一代動態化技術架構與選型綜述》 《Cube卡片技術棧解讀》歡迎大家回顧。 ”
小程式作為動態化或者跨端開發的一種技術棧,在業界成為事實標準。Cube 作為一種輕量級小程式技術棧,具有體積小、啟動快、記憶體佔用低等特點,也比較適合“即用即走”的小程式場景。以下將重點介紹 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 引擎對比:
Web |
Cube |
||
DSL |
AXML |
:white_check_mark: |
:white_check_mark: |
CSS |
:white_check_mark: |
部分支援 |
|
DOM |
:white_check_mark: |
不支援(有部分替代的介面) |
|
Component2 |
:white_check_mark: |
:white_check_mark: |
|
外掛 |
:white_check_mark: |
不支援(規劃中) |
|
元件 |
:white_check_mark: |
部分支援 |
|
開發工具 |
釋出打包 |
IDE/CLI |
CLI |
JS 除錯 |
:white_check_mark: |
:white_check_mark: |
|
預覽 DOM |
:white_check_mark: |
:white_check_mark: |
|
編輯樣式 |
:white_check_mark: |
:white_check_mark: |
|
特性 |
JS 上下文 |
每個業務一個 Worker |
所有業務共享一個 Worker |
佈局 |
CSS 裡各種佈局 |
CSS 裡常用佈局 |
|
樣式 |
CSS 全集 |
CSS 子集 |
|
JS 引擎 |
V8/JSC/JSI |
V8/JSI/JSC/QuickJS |
|
特點 |
效能上 |
啟動較慢,記憶體佔用較大 |
啟動快,體積小,記憶體佔用低 |
技術演進
讓小程式業務低成本適配 Cube 渲染小程式,需要做三方面的工作:
-
擁抱 Web 技術,補齊前端開發常用的能力:包括 CSS,小程式元件等;
-
完善相關工具:包括開發,除錯,Profile,釋出,打包等;
-
針對 Cube 的架構特點,深入優化,並拉開和 Web 渲染的差異。提供更好的使用者體驗。
新的流式佈局(Flow Layout)
最初 Cube 小程式使用只支援 Flex 佈局 Yoga 用於佈局計算。後面升級成支援 Block,Flex,Inline-Block等多種佈局方式的 Flow Layout。從而解決開發者只能使用 Flex 佈局的困擾。目前兩個佈局引擎 Cube 內部都支援。其中 Flow Layout 主要用在小程式,Yoga 用在卡片。兩者能力差異如下:
Yoga |
Flow Layout |
|
display: none |
:white_check_mark: |
:white_check_mark: |
display: flex |
:white_check_mark: |
:white_check_mark: |
display: inline |
:x: |
:white_check_mark: |
display: block |
:x: |
:white_check_mark: |
display: inline-block |
:x: |
:white_check_mark: |
display: inline-flex |
:x: |
:white_check_mark: |
display: -webkit-box |
:x: |
:white_check_mark: |
display: grid |
:x: |
可以擴充套件支援 |
支援 CSS 樣式表
老版本的 Cube 只支援內聯樣式和簡單的 CSS 選擇器;然而小程式並沒有約束 CSS,因此 Cube 擴充支援 CSS 樣式表,樣式繼承,多種選擇器等。從而使得 Web 渲染切換到 Cube 渲染,適配成本大大降低。甚至部分小程式可以做到在小程式 IDE 裡基於 Web 渲染開發,然後打包成 Cube 渲染產物在真機上預覽。前端同學無需進行過多的修改和適配。
新老 Cube 版本,選擇器支援上的差異如下:
老版本 Cube [1] |
新版本 Cube |
|
內聯樣式 |
:white_check_mark: |
:white_check_mark: |
id 選擇器 |
:white_check_mark: |
:white_check_mark: |
類選擇器 |
:white_check_mark: |
:white_check_mark: |
元素選擇器 |
:white_check_mark: |
:white_check_mark: |
樣式繼承 |
:x: |
:white_check_mark: |
偽類、偽元素 |
:x: |
:white_check_mark: |
屬性選擇器 |
:x: |
:white_check_mark: |
選擇器分組 |
:x: |
:white_check_mark: |
分組選擇器 |
:x: |
:white_check_mark: |
組合器 |
:x: |
:white_check_mark: |
@keyframes |
:white_check_mark: |
|
@fontface |
:x: |
:white_check_mark: |
@media |
:x: |
可擴充套件支援 |
注:
-
[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個問題:
-
效能問題:特別是 Android 下,利用 Android 平臺層的介面實現文字佈局計算,導致在文字較多的情況下,佈局耗時在渲染整體耗時裡佔比較高;
-
富文字特性:富文字以及許多文字特性支援較麻煩;
-
各平臺上實現文字效果存在細節差異或者相容性問題。
針對上述問題,在 Flow Layout 基礎上增強支援 Inline Text 佈局計算文字。基於 Inline Text 可以較輕鬆實現以下富文字,圖文混排,分詞,自動換行等。
1.富文字
2.自動換行和分詞
Inline Text 實現前後的文字樣式對比如下:
平臺層 Text |
Inline Text |
|
width: fit-content |
:x: |
:white_check_mark: |
overflow-wrap: break-word 或 anywhere |
:x: |
:white_check_mark: |
word-wrap: break-word 或 anywhere |
:x: |
:white_check_mark: |
text-align: jusify |
:x: |
待支援 |
text-align-last text-align-start |
:x: |
待支援 |
text-emphasis |
:x: |
待支援 |
text-decoration: overline |
:x: |
待支援 |
text-decoration-color |
:x: |
待支援 |
line-break |
:x: |
待支援 |
word-break |
:white_check_mark: |
|
white-space |
:white_check_mark: |
|
vertical-align |
:white_check_mark: |
|
font-family |
:white_check_mark: |
|
font-face |
:white_check_mark: |
|
font-weight |
:white_check_mark: |
|
float |
:white_check_mark: |
|
clear |
:white_check_mark: |
|
line-height |
:white_check_mark: |
注:
-
假設原有 Cube 採用平臺層介面實現的文字特性稱為: 平臺層 Text ;
-
表示實現細節上不完善或者不完全支援;
-
在 Inline Text 基礎上可以實現功能豐富的富文字元件;
-
值得一提的是:該實現非常精巧,對於 Cube 包體積只增加了 170KB。具體細節後續文章詳細探討。
文字佈局計算耗時對比(文字節點較多場景):
Yoga 平臺層 Text |
Flow Layout 平臺層 Text |
Flow Layout Inline Text |
|
佈局耗時 單位(ms) |
456 |
763 |
170 |
採用 QuickJS 替代 V8
V8 雖然是效能最高的 JS 引擎,但是存在記憶體佔用大,初始化較慢等不足。在 IoT 或者低端裝置上這些不足會被放大。因此在這些裝置上,Cube 採用 QuickJS 取代 V8。一方面降低記憶體佔用,另外一方面提升初始化效能。
Cube 內部目前適配了多個 JS 引擎,具體如下:
-
在 Android 移動端上使用 V8 和 JSI
-
iOS 上使用 JSC
-
IoT 等低端裝置上使用 QuickJS
另外我們在開源 QuickJS 基礎上做了些優化工作。優化的結果大致如下(後續文章將詳細介紹):
V8 Bench |
開源 QuickJS |
優化後 QuickJS |
效果 |
DeltaBlue |
627 |
731 |
+16.5% |
Crypto |
893 |
933 |
+4.5% |
Ray Trace |
459 |
1194 |
+160% |
Earley Boyer |
973 |
1906 |
+95.9% |
RegExp |
178 |
265 |
+48.9% |
Splay |
756 |
1783 |
+135.8% |
Navier Stokes |
1644 |
1643 |
0% |
分數(越高越好) |
672 |
991 |
+47% |
支援動畫和多媒體元件
除了上述基礎元件和能力之外,動畫和多媒體也是部分小程式不可缺少的。因此我們擴充套件支援了 Video , Canvas 、 Lottie , Live Player 等元件支援。並應用於 TV 大屏小程式、小遊戲以及直播場景上。
在低端裝置上,如何提高動畫幀率並且降低記憶體佔用也做了深度的優化。以下是 Video 和 Canvas 元件在小程式中的效果圖:
|
|
Cavas 元件 |
|
|
|
Video 元件 |
支援多種模式的小程式產物
目前 Cube 支援多種模式的小程式產物: Native , Cube , Shared 。
-
Native模式:對應的是舊的 Cube 渲染小程式模式,不支援 CSS 樣式表,只能支援內聯樣式和有限的幾種 CSS 選擇器。效能最高,相容性較低;
-
Cube模式:在 Native 模式進化而來,支援 CSS 樣式表和多種 CSS 選擇器。效能良好,支援常用的 CSS 樣式和特性(包括樣式繼承,多種 CSS 選擇器);
-
Shared模式:為了降低 Web 渲染的小程式遷移或者過渡到 Cube 渲染而開發。在同一個小程式產物裡既支援 Web 渲染一部分頁面又支援 Cube 渲染一部分頁面。而且 Cube 渲染的頁面支援樣式表。這樣在效能和相容性平衡。小程式產物相對於 Web 渲染的小程式,產物體積增加不會超過 10%。
Native 模式 |
Cube 模式 |
Shared 模式 |
|
小程式產物體積 |
較小 |
中 |
稍大 |
小程式效能 |
高 |
高 |
稍低 |
小程式相容性 |
一般 |
稍高 |
高 |
新樣式 |
不支援 |
支援 |
支援 |
新佈局 |
支援 |
支援 |
支援 |
注:如果需要 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 裝置,還需要加速技術演進以支援更多的場景。歡迎大家一起來交流討論。
關注我們,每週 3 篇移動乾貨&實踐給你思考!
- 淘寶Native研發模式的演進與思考 | DX研發模式
- 前車之鑑:聊聊釘釘 Flutter 落地桌面端踩過的“坑” | Dutter
- 釘釘 Flutter 跨四端方案設計與技術實踐 | Dutter
- 前車之鑑:聊聊釘釘 Flutter 落地桌面端踩過的“坑” | Dutter
- Dutter | 前車之鑑:聊聊釘釘 Flutter 落地桌面端踩過的“坑”
- Dutter | 釘釘 Flutter 跨四端方案設計與技術實踐
- Swift 首次除錯斷點慢的問題解法 | 優酷 Swift 實踐
- Swift 首次除錯斷點慢的問題解法 | 優酷 Swift 實踐
- Swift 首次除錯斷點慢的問題解法 | 優酷 Swift 實踐
- MNN 引擎的稀疏計算方案設計與實踐
- 2022 支付寶五福 | “聯機版”打年獸背後的網路技術 RTMS
- 淘寶小程式體驗優化:資料分析和優化實踐
- Cube 技術解讀 | Cube 渲染設計的前世今生
- hyengine - 面向移動端的高效能通用編譯/解釋引擎
- 構建順滑自然的 Flutter 頁面
- 淘特 Flutter 流暢度優化實踐 · 二期
- 收藏!2022年全球IT基礎設施行業技術競爭格局分析
- 提升 Hybrid 體驗:餓了麼雙十一 PHA 框架技術實踐
- 優酷播放黑科技 | 自由視角技術的全鏈路策略與落地實踐
- 淘寶小程式體驗優化:資料分析和優化實踐