有段時間沒更新博客了,之前計劃由淺到深、從應用到原理,更新一些RN的相關博客,之前陸續的更新了6篇RN應用的相關博客(傳送門),后邊因時間問題沒有繼續更新,主要是平時空余時間都用來幫著帶娃了,不過還是要擠擠時間來總結下,目標是完成由淺到深、由應用到原理的RN系列博客,本篇算是屬于原理部分的博客,不過不在之前計劃中,本篇是本人在公司內部某事業群大前端月刊中發布的一篇純技術分享的博客,是基于Facebook的RNTester工程進行的TurboModule的原始碼分析,因為不涉及公司內部的敏感代碼及相關資訊,而且在公司內部發布受眾有限,所以就以個人名義同步到自己的博客中,與大家分享及交流,文中所述內容僅代表個人觀點,如有偏頗或不恰當之處還望指正,
一、簡介
Turbo Modules是升級版的Native Modules,是基于JSI開發的一套JS與Native互動的輕量級框架,用來解決在使用Native Modules時遇到的問題,本篇博客主要對Turbo Modules和Native Modules進行了對比,并對Turbo Modules的實作進行了探究,除了介紹官方給出的優化點外,還通過具體示例對Turbo Modules與Native Modules的通信耗時進行了對比分析, 后續會以iOS視角,結合原始碼補充JSI、Fabric等RN新架構中的實作原理,
下方是新舊架構種,NativeModule與TurboModule相關區別,下方會進行詳細展開,

二、為什么要推出Turbo Modules
1、Native Modules的缺點
下方是官方給出的Native Modules缺點,同時也是推出Turbo Modules的原因,
|
序號 |
總結 |
介紹 |
|---|---|---|
| 1 |
Native Modules不支持懶加載 |
在一個包中指定Native Modules有著更早的初始化時機,React Native的啟動時間隨著Native Modules的數量增加而增加,即使其中一些Native Modules從未使用過也會被創建,Native Modules還不能使用開源的LazyReactPackage進行懶加載,因為LazyReactPackage中ReactModuleSpecProcessor不能與Gradle一起運行,目前該問題尚未解決, |
| 2 |
Native Modules檢查JS與Native方法一致性較為困難 |
暫無簡單的方法可以檢查JavaScript呼叫的Native Modules是否在Native中被定義了,并且在熱更新時,暫無簡單的方式來檢查新版中JS代碼在呼叫Native Modules方法時入參是否正確, |
| 3 |
Native Modules以單例形式存在,其生命周期與橋關聯 |
Native Modules是以單例的形式存在,其生命周期與橋生命周期相關,該問題在Native與RN混編的APP中尤為明顯,因為RN橋可能會多次啟動和關閉, |
| 4 |
Native Modules的方法串列是在運行時進行掃描(多余的運行時操作) |
在啟動程序中,Native Modules通常被定義在多個包中,在運行時去遍歷,最終給出橋接的Native Modules串列而這些操作是完全不需要在運行時執行, |
| 5 |
Native Modules使用運行時的反射來實作的,完全可以放到編譯期來做 |
一個Native Module的方法和常量推斷是在運行時通過反射來實作的,這些操作完全可以放到編譯期, |
參考:官方Turbo Modules介紹
2、Native Modules VS Turbo Modules
下方對Turbo Modules與Native Modules進行了對比,關于Turbos Modules相關的內容下方會詳細展開,

三、Turbos Module關鍵特性探究
本篇wiki中的示例是基于RN官方的“RCTSampleTurboModule”來展開分析,該示例中使用Turbo Modules在Native側定義匯出一系列的方法,然后在JS側進行呼叫,其中有異步方法,也有同步方法,下方是核心代碼所在位置以及運行效果,


1、Turbo Modules執行程序概覽
首先通過官方示例來分析Turbo Modules的使用方式,在官方示例中創建了一個SampleTurboModule,在SampleTurboModule中匯出了一系列的Native方法供JS使用,其功能與Native Modules所做的事情一致,但是其實作方式上有著本質區別,下方是相關呼叫程序,
Turbo Modules在使用程序中的呼叫流程:
-
JS側:首先在JS側可以通過import的形式來引入相關Turbo Modules,而在Turbo Modules宣告時,會創建JS側的方法介面,該介面中宣告了一些Turbo Modules橋接的方法,我們可以通過該介面定義,使用CodeGen來生成JSI側相關的呼叫方法,以及OC/Java側的方法介面,從而達到介面一致性的目的,
-
JSI&引擎層:自定義Turbo Modules需要實作JSI相關方法,可以將JSI相關方法與OC/Java方法進行映射,而這一步相關的方法也是由CodeGen自動生成,
-
Native側:在上層代碼(OC/Java)中,可以基于生成的介面來實作相關的橋方法,在JS側最終呼叫時,會執行該方法,

-
(1)、JS側對SampleTurboModule的使用
在JS側宣告SampleTurboModule時,會創建對應的自定義JS介面,使用時可以根據介面提供的方法來確定使用場景,而JSI層及OC/Java層對應的自定義Turbo Modules代碼,可以通過該介面生成對應的代碼及相關協議,稍后在CodeGen中會詳細介紹到,而本部分主要介紹模塊的注冊及使用,
模塊注冊:在JS側通過TurboModuleRegistry.getEnforcing方法對RCTSampleTurboModule模塊進行匯出,并且宣告了一個Spec介面,其中包括了SampleTurboModule中宣告的相關方法,具體代碼如下:
1 /** 2 * Copyright (c) Facebook, Inc. and its affiliates. 3 * 4 * This source code is licensed under the MIT license found in the 5 * LICENSE file in the root directory of this source tree. 6 * 7 * @flow 8 * @format 9 */ 10 11 import type {UnsafeObject} from '../../Types/CodegenTypes'; 12 import type {RootTag, TurboModule} from '../RCTExport'; 13 import * as TurboModuleRegistry from '../TurboModuleRegistry'; 14 15 export interface Spec extends TurboModule { 16 // Exported methods. 17 +getConstants: () => {| 18 const1: boolean, 19 const2: number, 20 const3: string, 21 |}; 22 +voidFunc: () => void; 23 +getBool: (arg: boolean) => boolean; 24 +getNumber: (arg: number) => number; 25 +getString: (arg: string) => string; 26 +getArray: (arg: Array<any>) => Array<any>; 27 +getObject: (arg: Object) => Object; 28 +getUnsafeObject: (arg: UnsafeObject) => UnsafeObject; 29 +getRootTag: (arg: RootTag) => RootTag; 30 +getValue: (x: number, y: string, z: Object) => Object; 31 +getValueWithCallback: (callback: (value: string) => void) => void; 32 +getValueWithPromise: (error: boolean) => Promise<string>; 33 } 34 35 export default (TurboModuleRegistry.getEnforcing<Spec>( 36 'RCTSampleTurboModule', 37 ): Spec);
匯入后,其使用方式與Native Modules使用一致,具體如下所示:

(2)、NativeSampleTurboModuleSpecJSI具體實作(C++實作 - 基于JSI提供JS可呼叫的方法)
下方使用C++撰寫的NativeSampleTurboModuleSpecJSI即基于JSI為SampleTurboModule提供的具體實作類,該類繼承自ObjCTurboModule,而ObjCTurboModule繼承自TurboModule類,而TurboModule類繼承自HostObject類,該類是CodeGen自動生成,
相關代碼截圖
而上述的JSI_EXPORT本質上是__attribute__((visibility("default")))的宏定義,該屬性用于設定元件中類的可見性,
#define JSI_EXPORT __attribute__((visibility("default")))
下方是NativeSampleTurboModuleSpecJSI類的建構式中的具體實作,其中主要功能是使用methodMap將JS中的方法與JSI對應的方法實作進行關聯,而methodMap的key是JS側使用的方法名,value則是MethodMetadata物件,及JSI中宣告的方法,
上述在.h檔案中進行了類的宣告,下方是.mm檔案中的具體實作,以getString方法的具體實作為例,下方定義了一個名為__hostFunction_NativeSampleTurboModuleSpecJSI_getString的C++方法,該方法有一個型別為facebook::jsi::Value的回傳值(Value是JS相關資料型別在JSI中的一個映射,JSI中關于Value的解釋:Represents any JS Value (undefined, null, boolean, number, symbol, string, or object). Movable, or explicitly copyable ),
在JS中每次通過SampleTurboModule呼叫getString方法,都會執行下面的方法,實際作用是呼叫Native側實作的getString,并回傳相關值,
上述方法中四個引數如下所示:
-
&rt:第一個是當前JS的運行環境,Demo中使用的Hermes引擎,所以該引數為當前Hermes的運行時物件,
-
&turboModule:第二個引數是turboModule物件,即該示例自定義的SampleTurboModule對應的物件,也就是該方法屬于哪個Turbo Modules實體,如下所示,
-
*args:第三個引數就比較常規了,就是getString方法的入參,
-
count:則是該方法有幾個引數,此處的getString只有一個引數,那么Count = 1,

該方法實作中,呼叫了turboModule的invokeObjCMethod方法,invokeObjCMethod中傳入了getString方法的SEL,其中就會執行Objective-C中對應的getString方法,并把回傳值回傳出去,在invokeObjCMethod方法中,首先獲取當前Module的名稱和方法,然后開始打點,紅框中是關鍵代碼,如果是Promise,則創建對應的回呼,否則直接呼叫performMethodInvocation執行相關方法,

-
(3)、Native橋介面(協議)宣告 -- NativeSampleTurboModuleSpec
CodeGen還會自動生成NativeSampleTurboModuleSpec的協議,該協議遵循了RCTBridgeModule和RCTTurboModule(后邊會詳細介紹),該介面中宣告的方法都是在JS側要呼叫的方法,也就是橋方法,
-
(4)、RCTSampleTurboModule的創建(Native側方法的具體實作)
基于NativeSampleTurboModuleSpec協議來創建自定義的Turbo Modules類RCTSampleTurboModule,在下方類宣告中的注釋資訊中可以看出,該類100%與Native Modules系統進行兼容,在RCTSampleTurboModule類宣告時中遵循了RCTBridgeModule,在類的@implementation中實作了該協議中的相關方法,以及使用了RCT_EXPORT_SYNCHRONOUS_TYPED_METHOD、RCT_EXPORT_METHOD的方式進行方法匯出,目的在于兼容Native Modules,

上述代碼中的RCT_EXPORT_SYNCHRONOUS_TYPED_METHOD、RCT_EXPORT_METHOD等方法完全是為了兼容Native Modules,如果在你的APP中沒必要兼容Native Modules,在僅僅使用Turbo Modules的情況下,完全可以把上述Export方法換成正常的Objective-C的實作,
除了上述的兼容方法外,在Turbo Modules的使用中比較關鍵的就是getTurboModule方法,該方法是RCTTurboModule協議中宣告的方法,目的在于獲取自定義的Turbo Modules物件,getTurboModule的方法實作比較簡單,就是呼叫了一個C++的庫函式來對NativeSampleTurboModuleSpecJSI類進行實體化,
2、Turbo Modules的注冊與呼叫
下方是Turbo Modules注冊及實體初始化的相關流程,Turbo Modules的注冊程序確切說是TurboModuleRegister初始化程序,并不會創建相關Turbo Modules物件,
Turbo Modules的注冊程序如下:
-
TurboModuleManager物件創建:首先在橋創建時,會呼叫RCTCxxBridge.start方法,在該方法中會創建TurboModuleManager物件,
-
TurboModuleBinding初始化:然后在TurboModuleManager中會呼叫installJSBindingWithRuntimeExecutor方法,來呼叫TurboModuleBinding的install方法進行初始化,并且將turboModuleProvider與TurboModuleBinding進行關聯,
-
JS側注入__turboModuleProxy方法:在TurboModuleBinding的Install中,動態的為JS側全域global添加了一個__turboModuleProxy方法,JS側可以呼叫__turboModuleProxy方法來獲取對應的Turbo Modules實體,
注冊器初始化后,可以在JS側呼叫相關__turboModuleProxy來獲取物件了,具體流程如下:
-
JS側呼叫方式:首先在JS側import TurboModule,然后會呼叫JS側TurboModuleRegistry的getEnforcing方法,最終通過全域變數global執行__turboModuleProxy,
-
獲取Turbo Modules實體:最終在Native側會執行provideTurboModule方法,該方法中主要分為三步----獲取快取 -> 創建C++模塊實體 -> 創建ObjC/Java模塊實體,并將實體存入快取,下方在介紹Turbo Modules的懶加載時會詳細介紹,
-
JS側獲取實體并呼叫相關方法:經過上述程序,在JS側可以獲取相關Turbo Modules物件然后呼叫相關方法,
|
平臺 |
iOS |
Android |
|---|---|---|
|
流程 |
|
|
在JS側會呼叫TurboModuleRegistry.getEnforcing方法來加載自定義的Turbo Modules,具體代碼如下所示:
1 export default (TurboModuleRegistry.getEnforcing<Spec>( 2 'SampleTurboModule', 3 ): Spec);
而上述呼叫最侄訓執行到requireModule(),在下述方法中首先通過Bridgeless來判斷是否支持Turbo Modules,如果不支持則回傳同名的Native Modules,相反就會呼叫turboModuleProxy,而此處的__turboModuleProxy方法是通過global ( NodeJS.Global 型別,全域變數)獲取的,

而__turboModuleProxy方法則是在Native側通過運行時往JS的global上系結的一個方法,而__turboModuleProxy方法則是通過JSI的形式注冊關聯到JS側的,最侄訓呼叫到Native側jsProxy方法,從呼叫堆疊上可看出在Native側的呼叫鏈為 jsProxy -> getModules -> provideTurboModule,provideTurboModule方法會回傳對應的Module實體,如下圖所示:
以iOS側為例(Android實作方案類似,就不做過多贅述),provideTurboModule(入參為module name)方法中主要有三步:
-
第一步查找快取:首先查找快取,如果之前創建過對應的Turbo Modules物件,則直接回傳,
-
第二步創建并回傳對應的C++ modules:優先回傳對應C++ Module,
-
第三步創建并回傳平臺指定的Module:最后是創建并回傳平臺指定側Module,此處是iOS系統,使用的ObjC,所以回傳的是ObjCTurboModule,如果是安卓則回傳JavaTurboModule,
3、Turbo Modules懶加載機制
當第一次對Turbo Module進行import呼叫時,上面的TurboModuleRegistry.getEnforcing方法才會執行,進而才會創建對應的Turbo Module實體物件并進行快取,如果沒有對模塊進行import,那么對應的模塊將永遠不會初始化,

JS側首先讀取本地快取,因為OC可以直接跟C++互動,在讀取快取與創建C++物件時Java和OC有一些差異,OC可以直接創建C++實體,而Java必須通過C++創建,所以這里使用“Native側”統一表示,當快取讀取失敗時,會創建一個純C++實體(pure-C++ Native Modules),在這里Android側代碼中沒有給出實作,iOS側有自己的實作,如果這里創建成功,會寫入快取并且回傳給JS側,當pure-C++實體沒有成功創建,就會創建JavaTurboModule/ObjcModule實體,因為Java實體不能直接被JS呼叫,因此Android側會額外創建一個C++實體包裹這個Java實體,然后將這個C++實體寫入快取并回傳,
4、Turbo Modules的創建與銷毀
上一部分對Turbo Modules的創建程序進行了重點介紹,該部分注重介紹Turbo Modules物件的銷毀程序(以iOS側為例):
-
Turbo Modules實體創建:在JS側呼叫Turbo Modules時會創建相關實體(懶加載),并且將創建好的實體存入CacheMap,
-
RCTBridge的創建:在RN示例中RCTRootView創建時,會創建RCTBridge相關實體,
-
RCTBridge的銷毀:當RCTRootView銷毀時,則會釋放RCTBridge實體,在RCTBridge釋放后,會發送橋銷毀的通知,
-
ModuleCacheMap清空:RCTTurboModuleManager物件收到通知后,會清空ModuleCacheMap,

Turbo Modules的生命周期也是與RCTBridge系結的,當RCTBridge物件被釋放時,會發通知清除當前創建的Turbo Modules實體,在官方示例的AppDelete及RCTRootView創建時都會創建RCTBridge物件,也就是說Turbo Modules的生命周期是與RCTRootView的生命周期一致,具體分析如下:
-
在TurboModulesManager的,_invalidateModules方法中會對快取進行清除,而_invalidateModules在收到bridge銷毀后的通知時呼叫,
-
RCTBridge在官方示例的AppDelete、RCTRootView、RCTSurfaceHostingProxyRootView(為了兼容RCTRootView,便于往Fabric中的RCTSurface上遷移)中都有初始化,所以當RCTRootView釋放時其對應的RCTBridge物件也會被釋放,此刻就會發通知然后清除快取,而在AppDelete中的didFinishLaunching方法中,創建了RCTBridge物件,并將RCTBridge實體已引數的形式傳入了RCTRootView的構造方法中,所以在單bundle單頁面的情況下,每次退出頁面都會都模塊快取Map進行清空,


-
經過代碼分析,開發程序中的Command + R也會對Turbo Modules的快取進行清空,
5、介面一致性保障
(1)、Facebook官方工具(暫未正式公開對外使用)
CodeGen是一個開發工具,作用是靜態型別檢查器(Flow或TypeScript),目的是以自動化的形式來保證JS側與Native側的兼容性,用來解決之前檢查JS側介面與Native側介面一致性比較困難的問題,
The React Native team is also doubling down on the presence of a static type checker (either Flow or TypeScript) in the code. In particular, they are working on a tool called CodeGen to "automate" the compatibility between JS and the native side. By using the typed JavaScript as the source of truth, this generator can define the interface files needed by Fabric and TurboModules (elements of the new architecture that will be showcased in the third post) to send messages across the realms with confidence. This automation will speed up the communication too, as it’s not necessary to validate the data every time.
目前沒有找到官方關于介紹CodeGen使用的相關檔案,github上有人分享基于react-native-codegen生成代碼的工具,親測可用,(官方鏈接)

參考:
-
https://formidable.com/blog/2019/react-codegen-part-1/
-
https://github.com/react-native-community/discussions-and-proposals/issues/92
-
https://github.com/facebook/react-native/tree/master/packages/react-native-codegen
-
https://npm.runkit.com/react-native-codegen
(2)、微軟開源的react-native-tscodegen(可用)
除了上述FB的rn codegen,而微軟也開源了一款rn-tscodegin(Github地址),目的是根據TypeScript的介面,來生成Turbo Modules,在RN工程中親測可用,

四、Turbo Modules通信性能分析
官方相關檔案在介紹Turbo Modules的優化點時,沒有介紹其在通信程序中的優化點,本部分作為擴充,通過相關示例來探究Turbo Modules的通信程序中所做的事情,首先是執行緒切換上,其次是異步呼叫程序中的耗時探究,具體如下所示,
1、方法執行程序中的執行緒切換
-
同步呼叫:在Turbo Modules的同步方法調程序中沒有執行緒切換,都是在JS執行緒中完成的相關操作,所以如果在同步呼叫的方法中執行耗時操作勢必會造成JS執行緒阻塞,從而會影響其他JS執行緒的操作,
-
異步呼叫:而異步呼叫會有相關的執行緒切換,會將JS執行緒切換到主執行緒或者異步方法呼叫時指定的執行緒中,然后在相關執行緒中執行異步方法,執行回呼時又會切換到JS執行緒中,經過相關Demo驗證,一次執行緒切換的操作耗時可忽略不計,

(1)、iOS側切換執行緒的程序
同步方法:Turbo Modules同步方法的呼叫程序不存在執行緒切換問題,依舊是在JS執行緒,
異步方法:在CallBack或者Promise方法執行時,會走到下方的方法中,該方法呼叫了dispatch_async,如果methodQueue,是主執行緒對應的佇列,那么就會切換到主執行緒中,
iOS除錯驗證截圖同步呼叫

異步呼叫:

在iOS側上述的methodQueue是在RCTBridgeModule代理的methodQueue方法提供,該方法會在橋定義時進行實作,方法中如果回傳的是主佇列,那么就會切換到主執行緒,如果是創建的新佇列,則會創建一個新的執行緒,

(2)、Android側切換執行緒的程序
Android側的執行緒切換程序與iOS側大同小異,篇幅有限,就不做過多贅述,下方是安卓側執行緒切換相關流程,
2、異步呼叫耗時分析
同步呼叫無論在Native Modules和Turbo Modules中,執行程序都非常快(1~5ms),而異步橋的呼叫程序會慢一些(50 ~ 150ms之間),本部分著重探究異步橋的呼叫耗時,
首先對Turbo Modules與Native Modules的異步橋呼叫進行了測驗和分析,下方是相關資料,對應結果如下:
-
整體耗時:經過相關測驗,雙端Turbo Modules的異步通信耗時與Native Modules的通信耗時優勢并不明顯,兩者不相上下,當然官方沒有明確給出Turbo Modules在橋呼叫程序中速度更快,而說Turbo Modules在加載程序中會有一些優化,并且基于JSI實作的,JS可直接通過JSI呼叫OC方法,整體耗時變化不明顯,也算符合預期,
-
JS to Native:在JS呼叫Native相關方法是,Turbo Modules因為是通過C++代碼之間呼叫Java/OC對應的方法,執行結果比較快,無論是Android還是iOS,都在1ms左右,而Native Modules因為通過訊息佇列進行呼叫,性能會差一些,安卓在50ms左右,iOS在 20ms左右,
-
Native to JS:經過測驗發現Turbo Module在Native to JS的程序中要比Native Module慢幾十毫秒,這點有點出乎意料,稍后會進行分析具體是什么地方耗時,
測驗機型:
Android:Nokia X7 Android 9.0 4G+64G
iOS:iPhone 8 iOS12 2G+64G
測驗場景:
異步橋呼叫
測驗次數:
手動點擊100次,相關資料取平均值(Android & iOS的統計口徑及測驗代碼邏輯保持一致)
|
平臺 |
模塊 |
總耗時(ms) |
JS to Native(ms) |
Native to JS(ms) |
|---|---|---|---|---|
|
Android |
Turbo Modules |
118.79 |
1.56 |
117.23 |
|
Native Modules |
126.05 |
46.1 |
79.93 |
|
|
iOS |
Turbo Modules |
83.62 |
1.05 |
82.61 |
|
Native Modules |
89.8 |
22.16 |
67.64 |

3、異步呼叫程序中CallBack的耗時分析
callback程序,即一次Native to JS的執行程序,通過除錯可發現,最終是jsInvoke.invokeAsyn方法中的callback.call()方法耗時比較嚴重,該呼叫占據了整個Turbo Modules異步呼叫程序中的約95%的耗時,通過工具除錯定位,具體執行方法的耗時落在了Hermes引擎中的相關方法的執行上(Native Modules也有同樣的問題),
具體是Hermes引擎的哪些操作比較耗時?如何對其進行優化?最終能優化多少?在JSC和V8引擎上Turbo Modules表現如何?欲知后事如何,請聽下回分解,
strongWrapper->jsInvoker().invokeAsync([weakWrapper, responses, blockGuard]() { double start = [[NSDate new] timeIntervalSince1970] * 1000; auto strongWrapper2 = weakWrapper.lock(); if (!strongWrapper2) { return; } std::vector<jsi::Value> args = convertNSArrayToStdVector(strongWrapper2->runtime(), responses); strongWrapper2->callback().call(strongWrapper2->runtime(), (const jsi::Value *)args.data(), args.size()); strongWrapper2->destroy(); // Delete the CallbackWrapper when the block gets dealloced without being invoked. (void)blockGuard; double end = [[NSDate new] timeIntervalSince1970] * 1000; NSLog(@"Native Block End = %f",end - start ); });
從下方的分析程序中不難發現,一次CallBack程序中的操作耗時75ms,其中有73ms在Hermes引擎執行中,在除錯程序中因為沒有加載Hermes原始碼,具體耗時方法暫未定位,后續會繼續探索并嘗試給出相關優化方案, 具體除錯程序:

五、總結
Turbo Modules的實作基于JSI,較Native Modules有明顯優勢,但是在異步橋呼叫的程序中,優勢并不明顯,而且有較大優化空間,具體總結如下:
-
Turbo Modules加載程序更優:Turbo Modules支持懶加載,所以在加載程序及生命周期上比Native Modules有明顯優勢,
-
Turbo Modules解決了介面一致性:Turbo Modules使用程序中,可通過JS側的介面生成C++中間層的JSI代碼,并且生成對應的OC/Java的介面,可以基于介面來實作Native方法,從而達到了JS - Native兩側的介面一致性,而Native Modules沒有相關機制來保證JS與Native側的介面一致性,所以往往會造成JS側呼叫的Native方法被洗掉掉,進而造成Crash的情況,
-
Turbo Modules的方法加載效率更高:Turbo Modules的方法加載是編譯器就確定了,會經過JSI往OC/Java上映射相關的橋方法,在呼叫時直接執行,而Native Modules則是在運行時執行的,多余的運行時操作,影響性能,
-
Turbo Modules的JS to Native更快:無論是同步呼叫還是異步呼叫,JS to Native 呼叫程序中,Turbo Modules因為可以通過JSI直接呼叫OC/Java方法,所以其執行程序比,
-
Turbo Modules的Native to JS呼叫較Native Modules慢:實測,Turbo Modules在CallBack程序執行程序比Native Modules執行程序要長一些,表現不佳,具體原因分析中,宣告:
作者:青玉伏案
出處:http://www.cnblogs.com/ludashi/
本文著作權歸作者和共博客園共有,歡迎轉載,但未經作者同意必須保留此段宣告,且在文章頁面明顯位置給出原文連接,否則保留追究法律責任的權利,
如果文中有什么錯誤,歡迎指出,以免更多的人被誤導,
收簡歷:某互聯網公司,招聘iOS/Android靠譜工程師,入職后,可內部聯系樓主,有小禮品贈送,有意者可郵箱投遞簡歷:[email protected]
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/315934.html
標籤:其他
上一篇:CAD/DWG圖Web網頁可視化技術之柵格和矢量瓦片
下一篇:5、邏輯代數的基本定律和規則


