Save 37% off PRO during our Black Friday Sale! »

Catching up with TurboModule

860bf040d996601213e05747dd661c23?s=47 Tomoaki Imai
December 18, 2020

Catching up with TurboModule

未だ全容がはっきりしないReact Nativeの次世代アーキテクチャ TurboModules について話しました。

補足ブログはこちらです。 https://tomoima525.hatenablog.com/entry/2020/12/18/183556

860bf040d996601213e05747dd661c23?s=128

Tomoaki Imai

December 18, 2020
Tweet

Transcript

  1. Catching up with TurboModule Chomp, inc. CTO 今井智章 @tomoaki_imai

  2. HOW GOOD FRIENDS FOOD 2 • 外⻝体験を記録、友達とシェアできるサービス • “Chomp: Foodie

    Friends” で検索
  3. HOW GOOD FRIENDS FOOD Agenda • おさらい: Native Moduleとその仕組み •

    JavaScript Interface, TurboModule • TurboModuleのFAQ • (おまけ)TurboModuleを使ったパフォーマンス改善 on Android 3
  4. HOW GOOD FRIENDS FOOD おさらい: Native Moduleとその仕組み

  5. HOW GOOD FRIENDS FOOD Native Moduleとは • Native(Java/objC)とReact Native(JS)をブリッジする仕組み •

    Android, iOSのAPIやスレッドを開発者が使うことができる便利な機能 5
  6. HOW GOOD FRIENDS FOOD Native Moduleの仕組み 6 RNBridge(C++) JS React

    Native Native ModuleRegistory Java FooModule objC FooModule const {FooModule} = NativeModule ModuleRegistoryに登録されたモジュールに 応じて引数をJSONにパース NativeToJSBridge JSToNativeBridge MessageQueueThead 各タスクをキューとして ⾮同期に処理 • RN Bridgeを介して⾮同期的に処理される • 引数や返り値はJSONでやり取り
  7. HOW GOOD FRIENDS FOOD Native Moduleの仕組み 7 RNBridge(C++) JS React

    Native Native NativeModules ModuleRegistory Java FooModule objC FooModule FooModule const { FooModule } ModuleRegistoryに登録されたモジュールに 応じて引数をJSONにパース NativeToJSBridge JSToNativeBridge MessageQueueThead 各タスクをキューとして ⾮同期に処理 • RN Bridgeを介して⾮同期的に処理される • 引数や返り値はJSONでやり取り 課題 JSONパース処理によるオーバーヘッド ⾮同期処理によるパフォーマンスへの影響
  8. HOW GOOD FRIENDS FOOD JavaScript InterfaceとTurboModule

  9. HOW GOOD FRIENDS FOOD JavaScript Interface(JSI)とは • JavaScriptからC++のメソッドを直接呼び出すことができるインタフェース • C++で実装されたオブジェクトのリファレンスをJavaScriptに定義する

    • Native(objC/Java/C++)のコードをブリッジコードを必要とせずJSから同期的 に呼び出し、処理できる 9
  10. HOW GOOD FRIENDS FOOD C++ TurboModule • JSIを介してNative Moduleを同期的に呼び出す仕組み 10

    JS React Native Native global.__TurboModuleProxy (JSI) JavaTurboModule RCTTurboModule FooTurboModule(JSI) Java FooModule objC FooModule FooTurboModule(JSI) get(‘FooTurboModule’) JS層とC++層で対になっている JSIをバインドする部分。プラットフォーム別 にInvokeするモジュールがある
  11. HOW GOOD FRIENDS FOOD TurboModuleのFAQ

  12. HOW GOOD FRIENDS FOOD Q1. TurboModuleは現状使える? • Yes、だけど⼤変 • Native

    ModuleとJSIをバインドするC++コードは現時点の最新バージョン 0.64.xでは⾃前で書く必要がある • Facebook の React Native チームがFlow-Typeの型情報に基づいてバインド コードを⾃動⽣成する仕組みを実装中(2020年12⽉現在) 12
  13. HOW GOOD FRIENDS FOOD Q2. TurboModule対応は必要? • アプリ開発者 • 基本的に不要なはず

    • ⾃動⽣成されるC++コードをビルドするために追加の設定はいるかも • ライブラリ開発者 • JSIを⽣成するためにJSの型をFlowやTypeScriptで定義する必要がある 13 Ref: https://github.com/react-native-community/discussions-and-proposals/issues/195
  14. HOW GOOD FRIENDS FOOD Q3. TurboModuleの実装例は? • React Native Reanimated

    v2 • 宣⾔的にアニメーションを表現できるライブラリ • RN 0.62.x 以上をサポート 14 • React Native プロジェクトの sample • `packages/rn-tester/js/examples/TurboModule`配下 • 引数で与えられた値を返すだけのモジュール
  15. HOW GOOD FRIENDS FOOD (おまけ)TurboModuleを使った パフォーマンス改善 on Android

  16. HOW GOOD FRIENDS FOOD TurboModuleを使った起動時間の短縮? • TurboReactPackageはTurboModuleで使われるモジュールパッケージクラス • TurboReactPackageは初期化時にコンストラクタや無名クラスを⽣成しない •

    RNBridgeにNative Moduleを直接渡している • v0.61からReact Native⾃体のモジュール初期化に使われている • auto-linkされてないNative Moduleで使えば起動の⾼速化が⾒込める…!? 16
  17. HOW GOOD FRIENDS FOOD TurboReactPackageの導⼊ステップ • TurboReactPackageを継承したクラスを作る • getModule, createViewManager,

    getReactModuleInfoProviderを実装する 17 JSでrequireする名前
  18. HOW GOOD FRIENDS FOOD 検証 • auto-linkされてない10個のNative ModuleをTurboModule化 • releaseビルドのTTI(Time

    To Interact)をReactMarkerで3回計測した平均 18 Start モジュール読み込み完了 〜 使⽤端末: Samsung A10e (Android 9)
  19. HOW GOOD FRIENDS FOOD 結果 • ほぼ差なし! • コンストラクタで重い初期化処理を実⾏している場合、NativeModule数が更に多ければ結 果は変わるかも

    19 TurboReactPackage ReactPackage
  20. HOW GOOD FRIENDS FOOD まとめ • TurboModuleはJavaScriptとC++をバインドするJSIによって実現される • Native APIへのアクセスのオーバーヘッドを解消し、起動時間の⾼速化やイン

    タラクションのパフォーマンスを改善する • RN v0.61.0以上でTurboModuleが部分的に適⽤されているのでパフォーマン ス改善が期待できる 20