衡阳派盒市场营销有限公司

0
  • 聊天消息
  • 系統消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發帖/加入社區
會員中心
創作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內不再提示

Taro 鴻蒙技術內幕系列(二):如何讓 W3C 標準的 CSS跑在鴻蒙上

京東云 ? 來源:京東零售 馬銀濤 ? 作者:京東零售 馬銀濤 ? 2024-10-31 10:54 ? 次閱讀

作者:京東零售 馬銀濤

wKgZoWci8VSAR5I_AAMoUb8Ux_U384.png


基于 Taro 打造的京東鴻蒙 APP 已跟隨鴻蒙 Next 系統公測,本系列文章將深入解析 Taro 如何實現使用 React 開發高性能鴻蒙應用的技術內幕

背景

HarmonyOS 采用自研的 ArkUI 框架作為原生 UI 開發方案,這套方案有完善的布局系統和樣式控制,但是他的標準與 W3C 的 CSS 標準存在不一致性。這意味著,如果 Taro 直接使用 HarmonyOS 提供的樣式系統,開發者在使用 Taro 開發時會遇到非常多的樣式兼容性問題,寫出來的代碼也會失去跨平臺兼容的能力,與 Taro 多端統一開發的定位不符。如何抹平 ArkUI 標準和 W3C 的 CSS 標準之間的差異成了一個重中之重的任務。

本文將介紹 Taro 處理 CSS 的全流程,剖析將不同的 CSS 樣式轉換為 ArkUI 樣式遇到的問題和對應的解決方案。

CSS 樣式和 ArkUI CAPI 樣式的差異和抹平

1、樣式書寫方式不一致

以幾個我們日常會使用到的屬性為例,下面的分別是 CSS 的寫法和 ArkUI CAPI 的寫法。

wKgaoWci8VWAXqneAADfO_UCT1M266.png

wKgZoWci8VeAf8WKAATrVO4UNz8495.png

對比可以看出,CSS 樣式和鴻蒙樣式在單位系統和數據表示方式上存在顯著差異。CSS 提供多樣化的尺寸和顏色單位,而 ArkUI 的 CAPI 接口采用更統一的表示方式。

ArkUI 的 CAPI 接口將所有尺寸統一為 vp 單位,顏色采用 0xAARRGGBB 格式的 uint32 類型,對于漸變和 transform 等復雜樣式屬性,更是需要轉換為顏色停止點和角度值列表和矩陣運算,這樣的接口簡潔但需要調用者根據具體場景完成必要的單位轉換。


wKgaoWci8VeAMpl0AACbu5hN2cU359.png

一個頁面通常會包含非常多的樣式規則,如果所有的單位轉換都放在運行時候完成,必定會造成明顯的性能問題。因此,我們選擇提前完成部分轉換。HTML 節點的樣式主要來源于 CSS 和 Style 屬性。CSS 樣式通常是靜態的,可以在編譯階段進行轉換。為此,我們基于 lightningCSS 開發了一個 Rust 插件。該插件通過遍歷項目 CSS 的抽象語法樹(AST),將其轉換為 ArkUI 的 CAPI 接口可直接使用的數據結構。


wKgaoWci8VmAGATvAAFwlCNt6uA933.png

wKgZoWci8VqAAYWKAAHbkyBQRRM542.png

而對于 Style 屬性,其內容在運行時才能確定,因此必須在運行時進行轉換。在 React 的語法中,Style 可能以字符串形式呈現,也可能是 CSS 屬性名和屬性值的鍵值對。為了有效解析 Style,我們針對各種類型的 CSS 語法寫了一系列小型的 CSS 語法解析邏輯。這些邏輯能夠從各種不同格式的字符串中準確匹配出屬性值并進行轉換。

雖然這種方法需要在運行時進行語法分析,但考慮到 Style 屬性通常只包含有限的樣式,加上 C++語言的高效執行特性,這種實時轉換對性能的影響可以忽略不計。更為重要的是,這些運行時的 CSS 語法解析邏輯可以為后面 Taro 支持 CSS 變量提供能力支持。


2、布局存在差異

除了書寫方式的差異,ArkUI 有很多布局屬性的行為在細節上也和 W3C 的布局屬性存在著不小的差異,比如鴻蒙的絕對定位相對父級定位,Web 的絕對定位相對最近的已定位祖先元素定位,并且鴻蒙的定位不支持 right 和 bottom(早期)。

wKgaoWci8VqAEhdEAABXyKzeG8w396.png

web可以通過margin的auto實現居中,鴻蒙能通過flex實現居中。

wKgaoWci8VuAX2NBAABFIB7vWV0760.png

同時, ArkUI 的 CAPI 接口缺少一些 Web 常用功能,如 calc() 計算和百分比設置支持。為消除這些差異,我們選擇采用 Yoga 作為布局引擎,而非使用鴻蒙原生提供的布局。Yoga 是 Facebook 開發的開源跨平臺布局引擎,實現了基于 Web 標準的 FlexBox 布局算法。使用 Yoga 可以很容易地實現對大部分 CSS 布局屬性的支持,讓兩端的差異縮小 。

在具體實現中,我們需要在構建 Taro 節點樹的同時,構建結構一致的 Yoga 節點樹。

wKgZoWci8VyAcZDPAAF2kMFcseQ446.png

然后把原本直接設置到鴻蒙節點上的樣式屬性(如寬高、margin、padding、display 和 position)設置到 Yoga 節點上。經 Yoga 計算后,我們再從 Yoga 節點上讀取計算后的 width、height、x 和 y 值設置到鴻蒙節點上,從而實現鴻蒙端和 web 端的布局一致性。

wKgZoWci8V2AE3MdAAE0pkBXjbQ843.png


通過使用 Yoga 作為布局引擎,我們不僅解決了鴻蒙系統與 Web 布局之間的差異,還提高了跨平臺一致性。這種方法使開發者可以使用熟悉的 Web 布局概念,同時確保在鴻蒙平臺上獲得預期的布局效果。

樣式的工作流程

介紹完 Taro 適配 ArkUI 的 CAPI 樣式過程中遇到的問題和對應的解決策略之后,我們就可以來看看基于這些策略,鴻蒙樣式的整個工作流程是怎么樣的。

樣式初始化

首先,項目啟動后,編譯器處理后的樣式文件將第一個被加載到運行時環境。樣式處理邏輯會根據各個選擇器(selector)生成相應的樣式規則(StyleRule),即 CSS 屬性的鍵值對集合。

wKgZoWci8V6AZN-vAAEmqhITbrM703.png

根據 ClassName 匹配 StyleRule

React 在構建每個節點的同時,會通過 Reconciler 把 React 節點的 ClassName 和 Style 設置到相應的 Taro 節點上,這個時候我們就開始進入節點的樣式匹配環節。樣式處理會執行以下步驟:首先,從 CSSStylesheet 這個樣式集合里識別出與 className 相關的所有 StyleRule;然后,根據選擇器的優先級合并這些 StyleRule;最后,將合并結果與由 Style 生成的 StyleRule 合并,從而得出最終的樣式配置。

wKgaoWci8V-AZS7SAAJeRhqNLdM371.png

這里順帶提一下,CSS 除了可以書寫樣式之外,還可以書寫偽元素和關鍵幀動畫,這兩者在都沒辦法直接設置到鴻蒙的樣式里,在處理某個節點時,如果匹配到這個節點的樣式里包含偽元素,就會把這個偽元素轉換成 一次 insertBefore api 的調用,用這個新 insert 進去的子元素來承載偽元素的 StyleRule,舉一個例子,下面的 F 節點的 CSS 樣式里帶有一個 ::after 的偽類,那么當 F 節點匹配到這個樣式的時候,就會被插入一個子節點用來承載 ::after 對應的樣式。


wKgaoWci8WCAc-QEAAGJFHp0OQQ621.png

而對于匹配到關鍵幀的動畫,會把動畫對應的元素,動畫播放的次數、播放的方向、播放的緩動函數收集起來放到另外的線程,由這個線程算出元素每一幀對應的屬性值,并在元素當前幀的 StyleRule 設置完之后,設置到節點上,保證動畫的優先級一定是最高的。

樣式的應用

確定了節點對應的樣式表后,我們就到了把樣式應用到節點上這個環節了。這個環節我們會調用節點的 SetStyle 方法,遍歷 StyleRule 中的所有樣式。對于布局相關的屬性(如 display、position、float、flex、width、height、margin、padding),如需更新,會被設置到節點對應的 Yoga 節點上,同時為節點本身添加 layout_dirty 標記。接著,判斷是否有繪制相關的屬性需要更新,如果有,則設置到節點對象的臨時屬性上,并為節點添加 draw_dirty 標記。這些被標記的節點并不會立刻被處理,而是會被納入下一幀的樣式處理隊列中,這樣能避免同一幀多次設置同一個結點的相同屬性,確保樣式更新的高效性,同時也能保證布局屬性和繪制屬性設置到鴻蒙節點時的前后時序。

wKgZoWci8WGALZwRAAFqPgZBlLM461.png

在標記完所有需要更新的節點后,下一幀的樣式處理流程就會對這些節點進行處理。首先,系統會調用 Yoga 的 calcYGLayout 函數,讓 Yoga 從根節點開始對所有的 Yoga 節點進行測算。在此過程中,布局信息發生改變的 Yoga 節點會被打上 has_new_layout 的標記,節點上的信息也會被更新。

我們用一個例子來說明Yoga如何判斷布局變化的影響范圍:假設節點E的寬度改變,這可能影響到依賴父元素寬度的子元素以及由子元素撐開寬度的父元素。計算后,系統可能會更新A、B、C、E、F、H等節點。


wKgaoWci8WKAMcqAAAKje9TtoMU877.png

測算完成后,我們遍歷Yoga節點樹,找出標記為has_new_layout的節點,并將其width、height、x、y值更新到對應的鴻蒙節點上。這樣,所有節點的布局信息就更新完畢了。

布局更新完成后,我們再把前一幀中添加到樣式處理隊列的節點拿出來。將存儲在節點臨時對象中的繪制屬性轉移到鴻蒙節點上。在這個環節里大多數繪制屬性可以直接設置,少量依賴節點布局信息的屬性(如百分比形式的 background-size)也可以利用新計算出的布局信息來準確確定這些屬性的值。

樣式的更新

了解了初始化狀態的樣式工作流程后,我們再回過頭來看一下樣式更新部分的邏輯,在這一塊邏輯里,樣式的匹配和應用與前面的流程沒有任何區別,所以只是簡單介紹一下一個節點的樣式是怎么被更新的。

?Style更新

Style 的更新是相對比較好處理的一部分,因為 Style 的影響范圍只在節點的本身。當元素的 Style 更新時,我們只需要重新生成對應的 inline_style_,然后將其與通過 className 生成的樣式進行合并應用即可。這個過程相對簡單直接,因為不需要考慮對其他元素的影響。通過這種方式,我們可以確保元素的樣式得到準確更新,同時保持整體樣式系統的一致性和效率。

?ClassName更新

當元素的 ClassName 更新時,我們需要執行以下步驟來確保樣式正確應用:

1.識別包含新 ClassName 的所有選擇器規則。

2.根據 ClassName 在規則中的位置,確定需要重新進行樣式匹配的元素:

?目標元素選擇器:更新當前節點

?直接后代選擇器:更新直接子節點

?后代選擇器:更新所有子孫節點

這些規則適用于 className 的增加、刪除、修改和查詢操作。對于 className 的修改,我們將其視為先刪除舊 className 再添加新 className,并執行兩次規則匹配。

舉一個例子,當樣式規則和元素結構如下時:

.E .G {} .E .H {} .I > .J {} .I {}

wKgZoWci8WOAZMSWAAB7Md0wMSk784.png

為藍色的節點添加className I,為紅色的節點添加className E,那么需要要被更新的節點就有 F G H I J

wKgZoWci8WOAF_MqAACH9QeJyPE327.png


在實際應用中,我們還需考慮性能問題。對于大型應用或復雜的元素結構,頻繁的樣式重計算可能會影響性能。因此,我們采取了一種優化策略:找出需要更新的節點后,不會立即進行樣式重匹配,而是將這些節點標記為"臟"并放入更新隊列中。然后,我們在下一幀統一完成所有樣式重匹配的工作。這種方法可以有效減少重復計算,提高整體性能。


總結

通過本文,我們詳細闡述了Taro在處理CSS樣式與鴻蒙系統ArkUI框架之間差異的全流程。我們探討了樣式書寫方式的不一致性、樣式匹配和應用的復雜過程,以及樣式更新時的處理策略。這些功能和特性使得Taro能夠在保持跨平臺兼容性的同時,實現CSS樣式到鴻蒙系統的有效轉換。

作為開發者,我們深知這個過程中面臨的挑戰,但也為最終取得的成果感到自豪。通過這種方法,我們為開發者提供了一個統一且強大的多端開發解決方案,使他們能夠更加高效地開發跨平臺應用。

我們相信,隨著技術的不斷進步,未來還會出現更多的優化空間。我們將繼續致力于改進Taro的性能和兼容性,為開發者提供更好的開發體驗。同時,我們也歡迎社區的反饋和貢獻,共同推動Taro在多端開發領域的發展。

系列往期精選:

《京東鴻蒙上線前瞻——使用 Taro 打造高性能原生應用》

《Taro 鴻蒙技術內幕系列(一):如何將 React 代碼跑在 ArkUI 上》



wKgaoWci8WSAKbneAAD_Nxv9Mxc463.png

審核編輯 黃宇

聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網站授權轉載。文章觀點僅代表作者本人,不代表電子發燒友網立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規問題,請聯系本站處理。 舉報投訴
  • 鴻蒙
    +關注

    關注

    57

    文章

    2392

    瀏覽量

    43055
收藏 人收藏

    評論

    相關推薦

    AIGC入門及鴻蒙入門

    、小巧、功能強大等特點,能夠物聯網時代為用戶提供更加便捷、高效的服務。 2. 開發環境搭建: 下載并安裝DevEco Studio,這是華為官方為鴻蒙系統開發提供的集成開發環境。 配置開發環境,包括安裝
    發表于 01-13 10:32

    Taro 鴻蒙技術內幕系列(三) - 多語言場景下的通用事件系統設計

    作者:京東零售 朱天健 基于 Taro 打造的京東鴻蒙 APP 已跟隨鴻蒙 Next 系統公測,本系列文章將深入解析 Taro 如何實現使用
    的頭像 發表于 11-27 11:42 ?272次閱讀
    <b class='flag-5'>Taro</b> <b class='flag-5'>鴻蒙</b><b class='flag-5'>技術</b><b class='flag-5'>內幕</b><b class='flag-5'>系列</b>(三) - 多語言場景下的通用事件系統設計

    鴻蒙生態發布統一互聯技術標準

    期間,GIIC聯合拓維信息、開鴻智谷等多家企事業單位共同發布了《鴻蒙生態設備統一互聯系列技術標準》。這一標準的發布,旨在打破不同品牌和體系智能終端設備之間的壁壘,通過統一的
    的頭像 發表于 11-25 10:27 ?347次閱讀

    鴻蒙Taro實戰:01-搭建開發環境

    ` ## 創建鴻蒙項目 打開 DevEco,點擊 右上角`Create Project`, `Application` 處選擇 `Empty Ablity`, 點擊 `Next`, 進入配置頁,根據
    發表于 11-06 16:42

    Taro鴻蒙技術內幕系列(一):如何將React代碼ArkUI上

    基于 Taro 打造的京東鴻蒙 APP 已跟隨鴻蒙 Next 系統公測,本系列文章將深入解析 Taro 如何實現使用 React 開發高性能
    的頭像 發表于 10-25 17:24 ?381次閱讀
    <b class='flag-5'>Taro</b><b class='flag-5'>鴻蒙</b><b class='flag-5'>技術</b><b class='flag-5'>內幕</b><b class='flag-5'>系列</b>(一):如何將React代碼<b class='flag-5'>跑</b><b class='flag-5'>在</b>ArkUI上

    鴻蒙Flutter實戰:07混合開發

    # 鴻蒙Flutter實戰:混合開發 鴻蒙Flutter混合開發主要有兩種形式。 ## 1.基于har 將flutter module打包成har包,原生鴻蒙項目中,以har包
    發表于 10-23 16:00

    騰訊突然宣布,微信鴻蒙版要來了!

    提供了一種高效的方式來處理大量的鍵值對數據,特別是需要頻繁讀寫的場景下。 直白來說,想要讓 「微信」 成功運行在原生鴻蒙上邊,就得先把這個底層組件適配搞定才行,這可能是微信適配鴻蒙較慢的原因,現在,難
    發表于 04-30 19:34

    鴻蒙OS崛起,鴻蒙應用開發工程師成市場新寵

    技術勢在必行,因此,鴻蒙應用開發工程師的需求也越來越大 。與傳統的移動應用開發工程師相比,掌握鴻蒙技術的工程師更加搶手,而且招聘時,企業也
    發表于 04-29 17:32

    Arm新Arm Neoverse計算子系統(CSS):Arm Neoverse CSS V3和Arm Neoverse CSS N3

    Arm宣布了兩款新的Arm Neoverse計算子系統(CSS),它們基于“迄今為止最好的一代Neoverse技術”。是什么這些新產品擁擠的計算
    的頭像 發表于 04-24 17:53 ?1190次閱讀
    Arm新Arm Neoverse計算子系統(<b class='flag-5'>CSS</b>):Arm Neoverse <b class='flag-5'>CSS</b> V<b class='flag-5'>3</b>和Arm Neoverse <b class='flag-5'>CSS</b> N<b class='flag-5'>3</b>

    鴻蒙OS開發實例:【HarmonyHttpClient】網絡框架

    鴻蒙上使用的Http網絡框架,里面包含純Java實現的HttpNet,類似okhttp使用,支持同步和異步兩種請求方式;還有鴻蒙版retrofit,和Android版Retrofit相似的使用,解放雙手般優雅使用注解、自動解析json
    的頭像 發表于 04-12 16:58 ?895次閱讀
    <b class='flag-5'>鴻蒙</b>OS開發實例:【HarmonyHttpClient】網絡框架

    首個鴻蒙生態創新中心深揭幕,開啟鴻蒙產業新篇章共繪鴻蒙原生應用開發新篇章

    首個鴻蒙生態創新中心深揭幕 開啟鴻蒙產業新篇章 2024年3月19日,鴻蒙生態創新中心揭幕儀式
    發表于 03-20 09:55

    與華為鴻蒙簽約,將啟動鴻蒙原生應用開發

    通過這項合作,零汽車計劃深化鴻蒙生態、技術優勢互補和商業可持續發展方面的合作。目前,其首款SUV C11已采用四葉草新型智能集成電子電氣
    的頭像 發表于 03-15 16:11 ?749次閱讀

    2024款鴻蒙OS 最新HarmonyOS Next_HarmonyOS4.0系列教程分享

    ,經過我們測試HarmonyOS5 Api10 和HarmonyOS4 Api9用法也基本一樣,99%的代碼是通用的。根據華為鴻蒙生態推廣部門介紹HarmonyOS5預計2024年3月份正式發布
    發表于 02-28 10:29

    那些杠鴻蒙的現在怎么樣了?

    公開課已走進135家高校,305所高校學生參與鴻蒙活動,286家企業參加鴻蒙生態學堂,38萬+開發者通過鴻蒙認證。 4…… 從這一系列數據來看,足以
    發表于 02-16 22:03

    鴻蒙系統優缺點,能否作為開發者選擇

    鴻蒙技術并不完全成熟,未來挑戰難度大。與Android、ios等頭部操作系統形成對立,競爭巨大。 鴻蒙的優點: 國家主推系統,必定會推向全國范圍。鴻蒙市場廣闊。
    發表于 02-16 21:00
    真人百家乐平台排行| 百家乐平注法技巧| 百家乐真人游戏娱乐平台| 全讯网25900.com| 上思县| 中国百家乐官网软件| 百家乐单跳| 大发888游戏网站| 至尊百家乐官网贺一航| 百家乐打印机分析| 威尼斯人娱乐平台开户| 百家乐官网有技巧么| 百家乐官网平注法口诀技巧| 百家乐园首选| 娱乐城百家乐官网论坛| 百家乐官网园天将| 全讯网3344111| 百家乐官网信用哪个好| 百家乐路单资料| 大发888娱乐城官网下载真钱| 百家乐官网注册平台排名| 百家乐视频麻将下载| 澳门顶级赌场娱乐平台| 百家乐官网赌场高手| 百家乐投注网站是多少| 凯旋门娱乐城开户| 茅台百家乐官网的玩法技巧和规则 | 大发888娱乐城rfgjdf888bg| 钱百家乐官网取胜三步曲| 百家乐投注方法| 皇冠网上69691| 饿火命适合做生意吗| 1368棋牌游戏平台| 试玩区百家乐官网1000| 威尼斯人娱乐城澳门赌博| 百家乐官网数据程序| 澳门百家乐娱乐城注册| 法老王娱乐城| 百家乐发牌铲| 鼎丰娱乐城| 百家乐博彩技巧视频|