精品欧美一区二区三区在线观看 _久久久久国色av免费观看性色_国产精品久久在线观看_亚洲第一综合网站_91精品又粗又猛又爽_小泽玛利亚一区二区免费_91亚洲精品国偷拍自产在线观看 _久久精品视频在线播放_美女精品久久久_欧美日韩国产成人在线

RN框架在攜程旅行鴻蒙應用的全業務適配實踐

開發 移動開發
攜程作為鴻蒙生態在旅游行業的重要合作伙伴,早在鴻蒙服務卡片時期就和華為開始合作。2023年9月,華為宣布鴻蒙原生應用啟動開發,同年12月,我們完成攜程旅行鴻蒙Beta版本的開發,技術上基于Web+部分原生的方案實現。24年6月HarmonyOS Next系統正式內測后,為了讓鴻蒙生態的用戶使用到攜程一站式的旅行服務,我們開始在鴻蒙系統上對全業務進行適配。

一、RN在攜程業務使用現狀

2019年,攜程開始在線上使用RN框架,并結合自身的業場景,對RN框架進行了開發和改造,研發了CRN框架(以下簡稱CRN)。2021年,CRN成為攜程主流的開發框架。集團內有20+個App接入CRN框架,其中核心的App都已接入。攜程旅行App中,200+個業務Bundle在線上運行,業務頁面數量超過2000個,超過80%的業務使用CRN。

二、技術選型(為什么選擇CRN)

從新技術的選擇到落地的實踐上看,業務對技術的要求往往是以下幾個方面:

1)功能全,全量業務都能快速的適配上線

2)性能好,用戶體驗多端一致

3)成本低,復用現有在其他平臺的運行的代碼

為了滿足業務需求,鴻蒙的實現技術上我們選擇了CRN,主要考慮:

1)基建成熟度高:有配套研發/測試/發布/運營監控系統,內部交流活躍,知識沉淀深

2)業務適配成本小:業務不需要重新再開發一遍,可以使用現有的業務代碼

3)開發能快速上手:業務開發還是使用原有的技術進行開發,在鴻蒙上運行

4)產品迭代效率:支持每個周期的產品迭代,快速在鴻蒙系統的手機上線

三、CRN適配實踐

3.1 版本升級

線上攜程旅行App使用的React Native(RN)版本是0.70.1,而鴻蒙RN版本是0.72.5。因此,適配鴻蒙的第一步是將RN版本從0.70.1升級到0.72.5。

版本升級包含了如下幾個方面:

3.1.1 RN版本差異分析

我們對比RN 0.70.1 和 0.72.5 框架庫的差異,整體改動點不多。為了降低業務方升級成本,我們在框架底層對廢棄的組件和API變更做了兼容,盡可能減少業務使用方的改動。

3.1.2 CRN框架改造

CRN框架覆蓋了文檔、工具、開發框架、發布、監控、排障全鏈路。對應框架的改造也從這幾個方面進行。

1)在文檔方面,我們編寫了詳細的業務升級文檔,列出業務方需要關注的點和常見問題。

2)在工具方面,提供了一鍵式CLI升級工具,只需在業務工程執行一行升級命令,即可完成工程升級改造。

3)在開發框架方面,改造涉及點比較多,包括:

  • 對Native運行時升級,升級RN 0.72.5 核心庫,合并對官方RN庫的自定義改動點。
  • 對JS打包工具升級,支持現有的拆包邏輯,合并對官方RN庫的自定義改動點。
  • 梳理使用到的社區三方庫,統一三方庫版本升級至鴻蒙RN三方庫要求版本。
  • 對Hermes引擎進行升級,合并自定義改動點。
  • 對RN自定義組件和API進行新架構改造。

4)在發布方面,對現有的CRN發布系統進行改造,支持選擇鴻蒙平臺進行單獨發布。發布的產物下發和線上IOS/Android進行隔離,保證測試上線階段,不影響已經上架的IOS/Android應用。

待后續鴻蒙應用穩定,再支持一鍵同時發布IOS/Android/HarmonyOS Next平臺。

又考慮到業務場景存在一套代碼,跨RN版本發布。發布系統改造,支持了發布時根據發布單選擇的RN版本,自動選擇依賴配置進行打包發布。提升業務發布效率。

5)在監控方面,實現鴻蒙端的監控數據上報,接入到現有的監控系統,方便線上監控。

6)在排障方面,實現鴻蒙端的異常數據上報,接入現有排障系統,方便線上排障。

3.1.3 業務工程改造

1)業務方按照提供升級文檔和工具進行具體業務工程改造。

2)升級改造后,進行本地開發環境測試,發現問題,解決問題。

3)本地測試通過后,進行打包發布,進入集成測試階段。

在升級過程中,工作量最大的部分是“RN自定義組件和API實現新架構改造”。

這里先介紹下RN新架構。RN新架構是指從0.68版本開始后的架構。主要包括:

  • Turo Modules 模塊系統,替換老架構中的Native Modules,用于JS到Native的API同步調用。
  • Farbic 組件系統,替換老架構中Native Component,支持同步渲染。

由于鴻蒙RN只支持新架構,所以需要將RN自定義組件和API實現進行新架構改造。在攜程旅行App中,我們使用有100+的自定義組件和API。這部分的改造工作量非常大,建議在做適配時優先處理這部分工作。

3.2 差異化工作

在RN版本升級到0.72.5后,開始鴻蒙端特有的適配。

鴻蒙RN框架特點:

  • 已實現了官方RN大部分組件、API
  • 已實現社區常用的三方庫
  • 自定義組件和API需要應用開發自行實現

差異化工作:

1)自定義組件和API實現

  • 100+自定義組件和API,基于鴻蒙原生開發實現,再封裝提供給RN調用
  • 按優先級分階段實現這些自定義組件和API,保持上層JS接口不變

2)RN工程改造

  • 添加react-native-harmony和react-native-harmony-cli依賴庫
  • 適配Platform.OS,Platform.select等API
  • 實現xxx.harmony.js文件,邏輯與IOS保持一致
  • 升級三方庫版本,如react-native-gesture-handler,從1.X版本升級到2.X版本
  • 三方庫版本升級后,對不兼容的地方做適配

3.3 原生組件開發

攜程CRN框架經過近8年的迭代,業務線非常復雜,自定義的組件、turboModule有100多個。

在鴻蒙中適配CRN,首先面臨的工作就是將這些自定義組件、turboModule在鴻蒙原生端用ArkTS重新實現。

我們面臨以下幾個挑戰:

1)工作量

這些組件經過了近8年的迭代,開發負責人可能幾經易手。有些復雜組件,如信息流組件、自定義地圖、日歷組件、多媒體組件等,邏輯異常復雜,經過跟原開發負責人、產品等初步討論,工作量都超過單人一個半月。而我們面臨的是100多個組件、turboModule的重實現。

2)HarmonyOS Next逐步完善,與Android、iOS在某些特性上有差異

開發過程中發現了很多HarmonyOS Next功能不完善、存在若干Bug的地方,畢竟是一個新系統,我們與華為同學緊密合作,一一解決了問題,這個過程見證了鴻蒙系統的愈發成熟。

出于安全考慮,鴻蒙系統有一些新特性,比如選取圖片視頻進行編輯的場景,在Android、iOS中,申請用戶權限之后便可以拿到整個系統相冊的圖片視頻,這確實可能存在一些安全隱患。鴻蒙在最開始就切割了這一操作,即使App經用戶同意申請了讀相冊權限,也無法拿到系統主相冊的圖片視頻,本意是讓App直接跳到系統相冊選取圖片之后返回,只提供當次選中的圖片信息給App,從而徹底斷絕了App侵犯用戶隱私的可能。

但我們的多媒體場景比較復雜,用戶選取圖片、視頻后會跳入編輯頁,且可以重回相冊頁選擇其他圖片,也就是說我們的圖片視頻選擇頁與編輯頁存在聯動,鴻蒙提供的這種跳入系統相冊的方式顯示無法滿足我們的需求。

后續經過討論,鴻蒙提供了相冊Picker的方案,將系統相冊頁封裝為組件提供給開發者,我們的圖片視頻選擇頁可以內嵌相冊Picker,從而解決了聯動的問題。但這個需求從開始評審、開發、測試到最終實現,花費了幾個月的時間。

3)RN組件C化

在接入RN的過程中,發現鴻蒙中RN關鍵性能指標與Android、iOS有差距,華為鴻蒙RN團隊為了解決性能問題,提出了組件C化的方案。

簡單來講,就是將ArkTS實現的組件用C-Api重新實現一遍,華為方面給出的要求是容器結點(RN代碼中存在標簽<></>嵌套的組件)需強制C化。雖然攜程中這種必須C化的組件并不多,但也帶來了非常多的適配工作。具體可參考下篇-組件C化。

部分組件圖如下:

圖片


Fabric、TurboModule

最開始,我們在實現相關Fabric、TurboModule的時候,鴻蒙RN框架還沒有提供Spec文件CodeGen工具,全靠手寫。不過現在已經提供了相關工具,具體操作步驟可以參考相關文檔。

Spec文件生成之后,剩下的工作就是相關組件、TurboModule的功能橋接實現,邏輯較為簡單,實現相關功能就好。

需要注意的是:

  • RN代碼中存在標簽<></>嵌套的組件被視為容器結點,此類型組件需使用C-API實現。
  • 可以通過this.ctx獲取RNOHContext,進而獲取RNInstance,從而獲取一系列RN端JS傳入的信息,如View寬高、style等,也可執行發送事件、接收事件、獲取TurboModule進行其他操作等等。
  • 在RNInstanceImpl構造函數中有一個arkTsComponentNames字段,可以傳入所有我們自定義葉子結點Fabric組件的名稱,用于在RNOH SDK內部進行指令分發優化。實現ArkTS端Fabric組件后,需要將Fabric組件的名稱加入此列表中。
  • 假設存在實現過于復雜或者其他原因無法C化的容器組件,RNOH SDK內部指令優化代碼需修改(這也意味著RNOH SDK需重新打包編譯),關鍵代碼見下文‘性能優化-5.3 RN 指令精簡章節。

3.4 組件C化

經過與華為的詳細溝通,RN代碼中存在標簽<></>嵌套的組件被視為容器結點,此類型組件需強制C化。

也就是此類型的組件:

<RNComponent>

    <Text/>

    <Image/>

</RNComponent>

RNComponent算為容器結點

經確認,攜程端存在四個需強制C化的容器結點組件,分別為:

名稱

描述

SwipeoutView

可滑動組件

ScrollView

滾動組件

CustomScrollView

自定義列表組件

CRNModal

modal容器

簡而言之,需要把ArkTS端實現的組件用C-Api再次實現。

3.4.1 CRNModal C化

CRNModal 在開發測試過程中一步步探索了實現方案,經過多輪測試、方案討論調整,最終確定了C化方案。

方案一:嘗試使用系統Modal實現這個組件

后續測試過程中發現系統Modal的實現方案為系統Dialog,層級很高,攜程業務線會出現這樣一種場景,RN頁面打開Modal后點擊跳轉一個其他頁面,新打開的頁面會出現在Modal的下方,不符合需求,方案淘汰。

方案二:嘗試通過新跳轉一個透明頁面的方式實現modal

測試發現新跳轉一個頁面后,RN的點擊事件分發出現問題,無法響應任何事件。且我們App的路由方案為Navigation,經與華為方面溝通,Navigation C化難度非常巨大,短時間不可行。此方案淘汰。

方案三:嘗試在RN JS端創建modal

JS端創建一個style為position: 'absolute', zIndex: 999的容器,層級提高,顯示在其他組件上方來實現modal。測試發現調用顯示Modal的地方很多,可能會在一個嵌套很深的層級中,如果在這里嘗試展示這個zIndex: 999的容器,還是會有被遮擋的情況,最終此方案也被淘汰。

方案四:C++層進行插入

經過內部討論,這個modal應該展示在整個RN頁面層級的最上方,這在Android、iOS中都很好實現,但鴻蒙是一個聲明式的語言,無法拿到頁面實例,無法拿到父組件,也就無法進行插入。

但研究RNOH SDK之后發現,C化后的RNInstance實例在C++端持有一個XComponentSurface,所有RN頁面對應的Native組件都被添加顯示在這里,而XComponentSurface可以獲取rootView實例ComponentInstance,這是一個根控件,將這個根控件強轉為ViewComponentInstance之后,在ViewComponentInstance.cpp代碼中可以類似Android,獲取childCount,通過index添加child等等,進而可以實現在RN頁面層級最上方添加modal,最終也是依據此方案,實現了CRNModal組件。

流程如下:

圖片


3.4.2 開發注意事項

1)在CAPI instance中聲明的Node節點,必須在全局聲明,否則會導致node節點不能收到node_event等消息;

2)設置node屬性構建ArkUI_AttributeItem的時候,如果設置的值是一個ArkUI_NumberValue類型,需要指定size,這個size的計算必須除去類型的長度,如下:

ArkUI\_NumberValue value\[] = {{.i32 = alignItem}};
ArkUI\_AttributeItem item = {value, sizeof(value) / sizeof(ArkUI\_NumberValue)};

3)animateTo執行動畫,在組件析構之后還是會回調,需要控制好生命周期避免crash;

4)設置Stack背景,導致子組件布局錯誤,是因為Stack被作為同級組件從而導致子組件的postion參數異常,需要手動處理好position問題;

5)可以通過以下方式在C++層調用arkTS方法,獲取相關數據:

方案1:在ArkTS里實現一個TurboModule方法,然后通過rnInstance->getTurboModule<XXTurboModule>獲取對應的TurboModule,調用方法,獲取返回值。但此方案涉及C++與ArkTS的跨端調用,性能會差一些,優點是實現簡單。

方案2:通過ArkTSBridge,添加一個ArkTS方法的橋,然后就可以在C++里直接調用這個ArkTS方法。具體實現可以參考NapiBridget.ArkTSBridgeHandler里任意方法。此方案性能好,但實現起來稍微麻煩一點。

6)可以通過以下Api獲取設備的高寬

auto displayMetrics = ArkTSBridge::getInstance()->getDisplayMetrics();
 displayMetrics.screenPhysicalPixels.width / displayMetrics.screenPhysicalPixels.scale //直接獲取到是px單位,需要進行轉換,也可以自行修改TurboModle的初始化值:

四、遇到的問題和解決辦法

在升級適配過程中,我們遇到了一些RN新架構問題,還有一些鴻蒙RN特有的問題。

RN 新架構問題:

  • IOS Animated.timing 設置 useNativeDriver:true 后,內嵌按鈕無法點擊
  • IOS TouchableOpacity 內嵌 Aminated.View ,Aminated.View 開啟動畫變更位置后,無法點擊
  • IOS Image樣式設置 borderRadius 顯示不全
  • IOS minimumFontScale maxFontSizeMultiplier 不生效
  • Aminated.View 內嵌Modal組件,內部TouchableOpacity點擊不響應
  • FlatList、ScrollView stickyHeaderIndices 吸頂功能多次滑動后失效
  • Aminated.View 、Animated.ScrollView、layoutAnimation 動畫卡頓
  • 樣式中使用了zIndex屬性層級可能不生效,嘗試添加 position:relative屬性后生效
  • 組件需要設置默認高寬,不然布局展示可能發生截斷

由于動畫、樣式、性能影響較大,最終決定在RN 0.72.5版本(iOS/Andriod)中只使用Turbo Modules,不開啟Fabric模式,來規避掉這些問題。

但鴻蒙RN只支持新架構,新架構存在問題有些在鴻蒙端同樣存在。我們和華為伙伴緊密溝通來處理這些問題。對于無法規避問題只能業務側做兼容處理。

鴻蒙RN特有的問題:

問題:RN Modal彈窗顯示時,再打開一個H5頁面會顯示在Modal下面 

解決辦法:實現一個View層級的CRNModal替代RN Modal

問題:絕對定位中添加top:“auto”導致元素不顯示 

解決辦法:去除top:“auto”設置

問題:zIndex:-1元素不顯示 

解決辦法:在最外層的View添加collapsable={false}屬性

問題:position:absolute樣式漂移 

解決辦法:在外層的View添加collapsable={true}屬性

問題:react-native-harmony/metro.config 和現有的自定義metro配置沖突

解決辦法:提取react-native-harmony/metro.config中harmony平臺相關處理,合并到自定義metro插件中

五、性能優化

華為內部對鴻蒙系統寄予厚望,為了追求更好的用戶體驗,希望鴻蒙APP核心業務場景性能指標達成業內最佳水平。對攜程來說,大多數業務頁面都是RN,RN技術棧對性能指標非常敏感,很小的性能優化或劣化,都會大幅影響用戶體驗。

5.1 CRN預加載

默認情況下,我們會在頁面的生命周期中去加載rn_bundle,因為頁面已經進入生命周期開始展示了,加載bundle又會有一定的耗時,這種情況下,就會產生白屏現象。

攜程也存在某些頁面依賴接口數據且接口返回比較慢的情況,比如機票列表頁,在進入頁面白屏之后又會有長時間的骨架屏,用戶體驗差。

圖片

經過調研,攜程端基于系統的FrameNode能力,實現了CRN預加載方案,解決了上述問題。

5.1.1 FrameNode

圖片


鴻蒙中FrameNode是一個非常強大的能力,不光是各大廠商在用,官方ArkUI中也大量使用了FrameNode進行性能優化。

它的特點用一句話可以描述:后臺離屏渲染,前臺上樹展示。

利用這個特點,可以實現組件渲染與頁面展示的完全分離。也就是說組件的創建渲染不再依賴頁面的生命周期,這樣我們就可以做很多事情了。

但正因為FrameNode組件會在后臺真實渲染,它使用起來會有一定的風險,后臺渲染的組件可能會影響前臺行為,比如改變狀態欄顏色、彈Toast、彈Dialog等,這些都需要人為進行規避。

在RNSDK中我們對Toast、Dialog、狀態欄等行為的TurboModule調用,根據頁面狀態進行了攔截,頁面不可見時,上述這些TurboModule的調用都不會生效,而且會記錄最后一次攔截的行為及參數,在頁面變為可見時,恢復最后一次被攔截的行為。

基于FrameNode能力,實現了鴻蒙中CRN預加載的1.0和2.0方案,下文會詳細介紹這兩個方案。

另外需要注意的一點是,攜程在RN中使用FrameNode過程中,遇過一個困擾許久的問題:使用FrameNode加載RN頁面時,在某些比較復雜的頁面,會發生非常嚴重的JS阻塞現象,用戶的點擊、返回等操作行為被頁面渲染指令阻塞,遲遲得不到響應,極度影響用戶體驗。

經過與華為方面的聯合排查,發現是因為RNInstance初始化時傳入的參數:disableCnotallow=true導致。此參數會關閉React18一個性能優化的功能:微任務指令批量提交,從而導致在JS代碼setTimeout中進行setState時,指令立即提交,總指令數大幅增加,進而大幅影響RN指令處理效率。

大家如果也會在項目中用到FrameNode進行RN頁面的性能優化,在初始化RNInstance時,disableConcurrentRoot參數一定要傳false。

5.1.2 CRN分包

要理解我們CRN的預加載方案,首先要了解我們的分包邏輯,具體可參考文章:《近萬字長文詳述攜程大規模應用RN的工程化實踐》

總體而言,將業務bundle的加載分為兩部分: rn_common & rn_business。其中rn_common包含完整的基礎框架能力,rn_business則是具體的業務邏輯代碼。通過nativeRequire的方式,分行加載rn_business中的業務代碼,然后在加載了rn_common的空白頁面上進行渲染。

可以發現,CRN這種分包模式完美契合FrameNode,我們使用FrameNode預渲染一個加載了rn_common的空白頁面,這個空白頁面不會渲染UI元素且具備完整的框架能力,不會有任何影響前臺頁面的行為,等到頁面真正展示時,才去加載業務代碼rn_business,進行UI渲染,從而完美規避FrameNode的使用風險。

也正是基于此,我們實現了CRN預加載1.0的方案。

5.1.3 CRN預加載1.0

圖片


預加載1.0方案:

  • 在前置頁面通過FrameNode預加載一個RNSurface,利用這個RNSurface去加載rn_common,完成后可以理解為后臺存在了一個具備所有框架能力的空白頁面。
  • 用戶點擊跳轉RN頁面時,添加一個用戶幾乎不可感知的延時去加載rn_business。
  • 充分利用這個跳轉延時 + 頁面創建 + 頁面切換的動畫時間去加載業務bundle、渲染等。
  • 業務Bundle加載完成后,動態替換業務自定義的intialProps
  • 做到了rn bundle加載、 渲染與頁面生命周期的完全隔離。
  • 目前預加載1.0方案在全業務默認使用,基本解決了RN頁面首幀白屏問題。

在攜程的某些業務線中,頁面UI依賴網絡接口數據,且受外部接口影響,響應較慢。這時候,打開頁面會有較長時間的骨架屏loading,也非常影響用戶體驗。

如果在前置頁面中,我們可以大概率猜到用戶下一步跳入的目標頁面,那是不是可以利用FrameNode將目標頁面提前加載,且根據前置頁面的參數進行動態刷新,這樣用戶真正跳入目標頁面的時候,就可以直接上屏,達到秒開的效果。

基于此,我們實現了CRN預加載2.0。

5.1.4 CRN預加載2.0

圖片

預加載2.0方案:

  • 在前置頁面通過FrameNode預加載了一個真實的RN頁面,完成了加載rn_commom、rn_business、接口請求、渲染等一系列流程。
  • 前置頁面中影響下一個頁面關鍵參數發生改變時,發消息給后臺預加載的的RN頁面,RN頁面接收到事件,拿到關鍵參數后進行網絡請求,得到數據后對頁面進行刷新。
  • 用戶點擊跳轉到目標頁面時,直接將后臺已經預渲染好的頁面上屏展示。
  • 因為頁面已經在后臺被真實渲染,有影響前置頁面的風險,雖然我們在RN SDK層面已經做了一層攔截,但這種攔截不可能cover所有場景,所有接入了預加載2.0方案的業務都必須在上線前經過完整回歸測試。
  • 目前,我們在機票列表頁及火車票詳情頁使用了預加載2.0方案。

對比視頻:

性能優化關閉:


圖片

性能優化開啟:

圖片

5.2 RN TurboModule運行在Worker線程

前段時間我們在RN JS端對TurboModule調用加了一個埋點,統計TurboModule方法調用的耗時,后續也是根據這個埋點生成了一個報表,發現在鴻蒙中,TurboModule同步方法調用耗時比Android、iOS耗時長10倍,某些方法甚至慢100倍。

圖片


經過分析,在Android、iOS中TurboModule都是運行在單獨的子線程中,而在鴻蒙中,TurboModule都運行在主線程,主線程要承載一些別的任務比如頁面渲染、用戶操作行為響應等,這些行為會導致鴻蒙中TurboModule的調用被阻塞,耗時就長。比如下圖的Trace,如果TurboModule在UI線程運行,那就可能會被阻塞,阻塞的這段時間,js線程只能等待,而這段等待是毫無意義的。

圖片


前段時間,鴻蒙RN SDK也是加入了TurboModule運行在Worker線程這個能力。RNInstance在創建時會同步創建一個worker線程,專門用于TurboModule運行。我們要做的是對工程中TurboModule代碼進行適配改造,使之可以運行到worker線程中。

整個適配過程也存在一系列的問題。

首先,鴻蒙的ArkTS衍生自TS語言,基于Actor線程模型,內存不共享,線程間數據通信非常麻煩。

為了解決線程間通信流程繁瑣的問題,鴻蒙提供了Sendable注解,可以理解為被這個注解修飾的對象會在共享內存創建。但Sendable存在一個問題,Sendable對象的成員變量只能是Sendable對象或其他特定的數據類型,也就是說我們如果對一個對象進行Sendable改造,就必須對他的所有成員變量進行Sendable改造,也需要對成員變量的成員變量進行Sendable改造,那這個改造過程就存在指數級擴散的問題。

另外,Sendable注解提供的時候,我們大部分代碼都已經完成了,在這種成熟的大型項目中再重新進行Sendable改造的成本非常高,大家各自App如果還沒開始或者剛開始開發,一定要考慮Sendable適配的問題,比如數據類型默認使用collection下屬map、array,class默認添加Sendable注解等。

目前,我們適配完成了7個TurboModule,其他TurboModule做Sendable適配的成本非常高,正在逐步進行中。

5.3 RN 指令精簡

在鴻蒙中,RN支持兩套組件:C-API實現的組件以及原生ArkTS實現的組件。

C-API實現的組件性能更好,華為的支持力度更大,出于性能考慮,大多數廠商使用RN時,都會選擇C-API實現的組件。

C-API組件的Create、Insert、Update、Remove等指令不再需要傳遞給ArkTS側。僅僅幾個自定義的ArkTS組件需要將指令傳遞給ArkTS側。如下圖中綠色節點的指令。

圖片

鴻蒙RNOH SDK中有默認算法,可以保留葉子節點ArkTS組件的指令,如果項目內沒有ArkTS容器組件,RNInstance初始化時添加配置arkTsComponentNames就好。

但在攜程的業務中存在AdatpterMap這個容器組件,依賴系統花瓣地圖,這個地圖C化難度巨大,所以我們的AdatpterMap暫時也只能由ArkTS實現。

這就需要我們自己設計算法。在保證性能的情況下,完整保留AdatpterMap及其子組件的相關指令。

以下是關鍵代碼:

RNOHSDK/src/main/cpp/RNOH/MountingManagerCAPI.cpp::getValidMutations:

facebook::react::ShadowViewMutationList MountingManagerCAPI::getValidMutations(
  facebook::react::ShadowViewMutationList const& mutations) {


...
//需要特殊處理,保留容器組件及其子組件所有指令的容器組件名稱
std::unordered_set<std::string> whiteListArkTsComponentNames = {
    "AdapterMap", "AdapterMapMarkersContainer", "AdapterMapMarker"};
//第一次遍歷:只遍歷create,從前到后找到混合組件名稱,只保存tag
for (auto mutation : mutations) {
  if (mutation.type == facebook::react::ShadowViewMutation::Create) {
    ...
    //特殊保留地圖容器組件tag
    if (whiteListArkTsComponentNames
            .count(newChild.componentName)) {
      arkTsComponentTags.push(newChild.tag);
    }
  }
}


if (!arkTsComponentTags.empty()) {
  // 第二次遍歷:只遍歷insert,找到混合組件tag和它的子組件的tag。采用廣度遍歷方式,這里也只保存tag
  for (auto mutation : mutations) {
    if (mutation.type == facebook::react::ShadowViewMutation::Insert) {
       ...
       //保存地圖容器組件tag和它的子組件的tag
    }
  }
}


//第三次遍歷:根據2中齊全的tag,重新過濾所有指令,保留這些tag的create、insert、update、remove指令。
for (auto mutation : mutations) {
  ...
  //根據組件Tag,保留需要傳遞給ArkTS的所有指令
}
 return validMutations;
}

再來看下成果,測試RN頁面中,算法過濾的不需要傳遞到ArkTS側的指令數超過99.9%。

頁面

優化前指令數

優化后指令數

酒店首頁

3092

11

酒店套餐

2181

0

機票+酒店

496

2

酒店

3838

3

美食/購物

1542

3

5.4 分幀渲染

分幀渲染主要用在App的啟動優化中。首頁宮格存在兩屏,二屏在剛開始是不可見的,可以在首頁加載完畢之后再去加載宮格二屏。

圖片

分幀渲染可以監聽到幀渲染的回調,這樣就可以對頁面元素的加載優先級進行定制,將重要的元素優先加載,不重要或者不可見的元素后續加載。進而提升頁面的性能。

關鍵代碼:

private myDisplaySync?: displaySync.DisplaySync


updateStage() {
    if (this.stages == 0) {
      this.myDisplaySync = displaySync.create();
      this.myDisplaySync.start();
      this.myDisplaySync.on('frame', (frameInfo: displaySync.IntervalInfo) => {
        this.updateStage();
      });
    }


    this.stages++;
    if (this.stages == 3) {
      this.myDisplaySync?.stop();
    }
}
...


 build() {
    Column() {
      Scroll(this.scroller) {
        Row() {
          //默認加載宮格首屏
          if (this.stages > 0){
            this.genFirstCell(0)
          }
          //三個渲染幀之后,加載宮格二屏
          if (this.stages > 2){
            this.genFirstCell(1)
          }
        }
        ...
        }

接入分幀渲染,控制宮格二屏的渲染時機后,首頁的啟動耗時減少了20ms。

5.5 后續性能優化

華為鴻蒙RN團隊規劃有一個性能優化的feature,在這里簡單介紹下。

5.5.1 更換RN JS執行引擎:JSVM(基于V8)

JSVM相較hermers,預計可以提升20%的JS解析性能。前段時間華為提供了一個rn sdk,我們新建了一個分支驗證了一下這個JSVM,js的加載速度確實比hermes要快一些。但RN產物jsbundle的加載比hermes要慢,這意味著頁面的首屏性能會受到一定影響。這是我們非常關注的一個性能指標,問題得到解決之后,我們也會進行切換。

六、成果和未來規劃

經過4個月鴻蒙版本的開發和適配,2024年6月18日攜程在鴻蒙應用商店上架了首個全業務全場景的攜程旅行鴻蒙版應用。業務方在Android/iOS上的一套CRN代碼,只需經過簡單的適配,就能正常在鴻蒙系統上運行,甚至有些業務不需要修改,現有的代碼直接在鴻蒙系統上能完整的跑完業務流程。

未來,我們還會在以下兩個方面持續對鴻蒙CRN框架進行優化:

用戶體驗

用戶體驗和性能一直是我們關注的重點,CRN在鴻蒙系統上還有很大的優化空間。我們會持續在性能上繼續打磨和提升。

技術布局

為了追求高效率、低成本的研發模式,未來攜程業務開發會大量使用一碼多端的框架xTaro。后續xTaro會支持鴻蒙系統,真正實現讓業務的一套代碼能在多端多平臺多應用場景上全矩陣運行。

鴻蒙生態的發展是一個持續且快速的過程。隨著鴻蒙系統的不斷迭代升級和生態的逐步完善,我們會持續為用戶提供更加智能、安全、便捷的一站式的旅行應用。

責任編輯:張燕妮 來源: 攜程技術
相關推薦

2022-07-15 12:58:02

鴻蒙攜程華為

2025-06-24 09:51:47

2023-06-28 14:01:13

攜程實踐

2020-11-11 13:44:00

攜程旅行點擊量

2022-09-13 13:14:53

存儲服務

2024-07-25 11:58:35

2022-05-13 09:27:55

Widget機票業務App

2022-08-20 07:46:03

Dynamo攜程數據庫

2023-07-07 12:26:39

攜程開發

2022-08-12 08:34:32

攜程數據庫上云

2023-02-08 16:34:05

數據庫工具

2022-07-15 09:20:17

性能優化方案

2022-07-08 09:38:27

攜程酒店Flutter技術跨平臺整合

2009-06-19 09:52:46

Acegi安全框架Spring框架

2022-06-17 10:44:49

實體鏈接系統旅游AI知識圖譜攜程

2024-07-05 15:05:00

2023-08-18 10:49:14

開發攜程

2022-05-27 09:52:36

攜程TS運營AI

2022-12-15 21:02:54

圖調度框架
點贊
收藏

51CTO技術棧公眾號

天天干中文字幕| 国产日产欧美视频| 性猛交xxxx乱大交孕妇印度| 一区三区视频| 亚洲一级一级97网| 男生操女生视频在线观看| 日本aa在线| 久久网站热最新地址| 国产综合久久久久久| 国产精品18p| 欧美gay男男猛男无套| 精品国产髙清在线看国产毛片| 欧美 激情 在线| 性xxxxfjsxxxxx欧美| 国产亚洲1区2区3区| 91国产在线免费观看| 日本中文字幕在线| 一区二区影视| 国产一区二区三区毛片| youjizz.com国产| 国产亚洲人成a在线v网站| 午夜精品成人在线视频| 免费看av软件| 国产污视频在线| a级精品国产片在线观看| 91久久国产综合久久91精品网站| 日本熟女毛茸茸| 亚洲久久成人| 欧美日韩第一页| av最新在线观看| 国产精品欧美三级在线观看| 欧美大胆人体bbbb| 一区二区三区欧美精品| 欧美理论影院| 精品成人乱色一区二区| 国产成人一区二区三区别| 日本在线观看免费| 欧美极品少妇xxxxⅹ高跟鞋| 久久av一区二区三区亚洲| 99热这里只有精品1| 久久99热这里只有精品| 国产精品久久久999| 国产专区第一页| 亚洲一级影院| 欧美精品久久一区二区| 全网免费在线播放视频入口| 久久在线视频免费观看| 一区二区三区天堂av| 国产精品久久久久无码av色戒| 国产精品极品在线观看| 精品欧美乱码久久久久久| 一个人看的视频www| 久久久精品区| 日韩欧美激情四射| 亚洲妇女无套内射精| 最新精品在线| 亚洲精品在线免费观看视频| 任你躁av一区二区三区| av成人综合| 亚洲国产日韩欧美在线动漫 | 国产精品影视网| 国产日韩欧美在线看| 中文字幕自拍偷拍| 久久机这里只有精品| 成人免费在线网址| 国产99视频在线| 国产99精品视频| 精品久久久久久中文字幕动漫 | 91免费国产视频网站| 久久av一区二区三区漫画| 久久精品a一级国产免视看成人 | 欧美日韩三级在线观看 | 国产精品乱人伦中文| 亚洲一二区在线| bestiality新另类大全| 亚洲高清中文字幕| 任你操这里只有精品| 青草综合视频| 精品国产一区二区三区久久久蜜月 | 蜜臀av一区二区在线免费观看 | 中文天堂在线播放| 久久爱www久久做| 亚洲一区亚洲二区| 午夜影院在线视频| 欧美国产日本视频| av久久久久久| 日韩电影网站| 91精品国产综合久久福利| 蜜臀视频在线观看| 国产欧美日韩精品一区二区三区| 俺去亚洲欧洲欧美日韩| 久久网一区二区| 男女男精品网站| 国产精品免费一区二区| 高h视频在线| 一区二区三区国产精品| 国产欧美在线一区| 日韩一区二区三区高清在线观看| 日韩精品极品视频| 在线免费观看亚洲视频| 视频一区视频二区在线观看| 91精品天堂| 国产在线视频网| 一区二区三区久久| 五月婷婷丁香综合网| 国产精品极品| 久久成人亚洲精品| 伊人久久久久久久久久久久| 高清不卡一区二区在线| 亚洲bbw性色大片| 黄色漫画在线免费看| 欧美军同video69gay| 日本一区二区三区网站| 国产精品av一区二区| 国产有码一区二区| 久久久pmvav| 午夜伊人狠狠久久| a级大片免费看| 欧美r级电影| 日韩av电影中文字幕| 免费观看国产视频| 亚洲狼人国产精品| 手机免费av片| 日韩精品免费| 国产精品av在线| 亚洲av成人无码网天堂| 亚洲一区二三区| 九九热视频免费| 97人人精品| 国产精品美女主播在线观看纯欲| 水莓100在线视频| 亚洲一卡二卡三卡四卡五卡| 国产性生活一级片| 日韩情爱电影在线观看| 国产精品久久久久久久久久东京| 四虎精品成人影院观看地址| 亚洲第一狼人社区| 亚洲v在线观看| 亚洲天堂激情| 痴汉一区二区三区| 欧美日韩在线视频免费观看| 日韩欧美激情四射| 草视频在线观看| 国产99精品视频| 美女扒开大腿让男人桶| av成人男女| 欧美激情乱人伦一区| 国内精品久久久久久久久久| 亚洲猫色日本管| 原创真实夫妻啪啪av| 欧美体内she精视频在线观看| 亚洲综合精品伊人久久| 在线看一级片| 精品国产一区二区三区av性色| 欧美成人免费看| 国产91综合网| 日本在线xxx| 猛男gaygay欧美视频| 国产脚交av在线一区二区| 国产片在线观看| 欧美日韩亚洲不卡| 午夜剧场免费在线观看| 国产成人欧美日韩在线电影| 欧美一区二区激情| 欧洲亚洲一区二区三区| 欧美在线免费观看| 福利成人在线观看| 在线成人午夜影院| 国产一级视频在线| 久久综合久久综合亚洲| 婷婷六月天在线| 91成人免费| 国产一区福利视频| 日韩毛片免费观看| 久久精品免费播放| 狠狠综合久久av一区二区| 婷婷久久综合九色综合绿巨人| 爱爱免费小视频| 久久精品国产精品亚洲红杏| 色婷婷777777仙踪林| 欧美调教网站| 国产精品天天狠天天看| 香蕉久久aⅴ一区二区三区| 亚洲国产欧美一区| 一本色道久久综合亚洲| 午夜精品视频一区| 亚洲黄色网址大全| 成人午夜视频福利| 成人免费xxxxx在线视频| 一区二区电影| 欧美12av| 秋霞一区二区三区| 国产精品第100页| 丁香花高清在线观看完整版| 国产一区二区三区18 | 亚洲色图在线观看| 精品美女www爽爽爽视频| 黑人巨大精品欧美一区二区免费| 99热6这里只有精品| av电影在线观看不卡| 成 人 黄 色 小说网站 s色| 在线亚洲成人| 日韩视频 中文字幕| 日韩国产一区二区| 好吊色欧美一区二区三区四区| 日韩毛片免费视频一级特黄| 2019亚洲男人天堂| 三级网站视频在在线播放| 一区二区三区视频免费| 午夜福利视频一区二区| 日韩一区二区视频在线观看| japanese国产在线观看| 午夜不卡av免费| 国产乱国产乱老熟300| 日本一区二区成人在线| 黄色网址在线视频| 国产一区二区三区免费观看| 日韩欧美在线免费观看视频| 亚洲国产二区| 九一免费在线观看| 欧美hentaied在线观看| 日本一区免费在线观看| 欧美黄色录像| 国产精品久久亚洲| 国产亚洲亚洲国产一二区| 国产精品福利在线| 亚洲最大网站| 2018日韩中文字幕| 91超碰在线播放| 欧美日本精品在线| 哥也色在线视频| xxav国产精品美女主播| 91福利在线视频| 亚洲新声在线观看| 韩国免费在线视频| 亚洲男女性事视频| 天天在线女人的天堂视频| 日韩欧美精品三级| 亚洲毛片在线播放| 精品电影一区二区三区 | 国产成a人亚洲精| 久久久无码人妻精品无码| 国产精品主播直播| 日韩精品――色哟哟| 国产精品18久久久| 精产国品一区二区三区| 国产黄色精品视频| 国产乱淫av片| 99久久久国产精品免费蜜臀| xxxwww国产| 91美女在线视频| 久久精品一区二区免费播放| 久久嫩草精品久久久久| 欧美特级黄色录像| 中文字幕欧美三区| 乱老熟女一区二区三区| 亚洲色图在线播放| 久久久精品99| 午夜电影一区二区| 国内自拍视频在线播放| 欧美在线免费观看视频| 在线播放成人av| 91精品麻豆日日躁夜夜躁| 国产激情视频在线播放| 亚洲第一级黄色片| 欧美日本网站| zzjj国产精品一区二区| 女人天堂av在线播放| 国产91成人在在线播放| 91精品国产经典在线观看| 91精品在线国产| 成人av影音| 欧美一区二区三区四区五区六区| 日韩精品诱惑一区?区三区| 熟女视频一区二区三区| 亚洲电影在线| 成人在线观看a| 韩日av一区二区| 国产精品扒开腿做爽爽爽a片唱戏| 97se狠狠狠综合亚洲狠狠| 欧美性猛交xxxx乱| 亚洲黄色性网站| 欧美一区二区激情视频| 欧美理论片在线| 污污网站在线免费观看| 日韩在线视频导航| xxxx视频在线| 国产精品夜色7777狼人| 99这里只有精品视频| 日本亚洲自拍| 国产精品va| 婷婷丁香激情网| 成人一区在线观看| 国产真人真事毛片视频| 午夜激情久久久| 99国产精品久久久久99打野战| 亚洲精品国偷自产在线99热| 欧美18一19xxx性| 欧美在线不卡区| 欧美精品三级在线| 四虎影院一区二区三区 | 欧美激情精品久久久久久小说| 狠狠色丁香婷婷综合| 在线免费观看日韩av| 一区二区三区成人| 18国产免费视频| 亚洲福利视频网站| caopeng在线| 国产美女精彩久久| 国产一区二区三区亚洲| 99精品视频网站| 三级在线观看一区二区| 精品视频站长推荐| 亚洲美女屁股眼交| 91久久精品国产91性色69| 日韩精品在线播放| 韩国日本一区| 亚洲一区二区久久久久久久| 精品久久美女| 日韩手机在线观看视频| 99久久99久久久精品齐齐| 裸体武打性艳史| 精品视频在线免费观看| 国内在线免费高清视频| 青青久久av北条麻妃海外网| 黄色美女久久久| 永久免费在线看片视频| 麻豆精品新av中文字幕| 久久久久久久久久久久| 狠狠躁夜夜躁人人爽天天天天97| 女人18毛片水真多18精品| 欧美精品一区二区免费| 警花av一区二区三区| 在线天堂一区av电影| 日本欧美加勒比视频| 91精品人妻一区二区三区| 色综合久久中文字幕| 视频福利在线| 欧美中文在线视频| 亚洲第一论坛sis| 国产精品免费入口| 97久久精品人人做人人爽| 久久夜靖品2区| 亚洲电影在线看| 美女扒开腿让男人桶爽久久软| 国产精品免费看一区二区三区| 国产精品二区影院| 这里只有精品在线观看视频| 亚洲国产另类av| 日韩在线观看视频一区| 久久免费精品视频| 久久男人av| 凹凸国产熟女精品视频| 久久精品欧美一区二区三区麻豆| 亚洲av无码不卡| 日韩在线激情视频| 九九99久久精品在免费线bt| 国产精品8888| bt欧美亚洲午夜电影天堂| 香蕉影院在线观看| 中文字幕亚洲自拍| 国产午夜精品一区在线观看 | 日本视频在线免费| 在线成人av影院| 欧美人与牲禽动交com| 国产视色精品亚洲一区二区| 性欧美videos另类喷潮| 黄色av免费播放| 欧美一区二区网站| 超碰在线99| 亚洲a∨一区二区三区| 国产乱码精品一区二区三区忘忧草 | 国产三级在线| 成人h视频在线观看播放| 国精品一区二区| 免费看污黄网站在线观看| 在线播放欧美女士性生活| 成人影音在线| 色狠狠久久av五月综合| 国产一区二区在线视频| 国产精品美女久久久久av爽| 中文字幕v亚洲ⅴv天堂| 51社区在线成人免费视频| 亚洲午夜精品久久久久久人妖| 日本一区二区三级电影在线观看| www.久久成人| 国产99久久精品一区二区永久免费| 99视频精品视频高清免费| 中文字幕a在线观看| 欧美区视频在线观看| 成人三级高清视频在线看| 亚洲国产精品久久久久久女王| 国产精品一区二区久激情瑜伽| 日韩色图在线观看| 欧美老女人在线视频| 精品久久久中文字幕| 中国特级黄色大片| 欧美精品日日鲁夜夜添| 亚洲最大成人| 国产免费黄色一级片|