Slide 1

Slide 1 text

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

Slide 2

Slide 2 text

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

Slide 3

Slide 3 text

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

Slide 4

Slide 4 text

HOW GOOD FRIENDS FOOD おさらい: Native Moduleとその仕組み

Slide 5

Slide 5 text

HOW GOOD FRIENDS FOOD Native Moduleとは • Native(Java/objC)とReact Native(JS)をブリッジする仕組み • Android, iOSのAPIやスレッドを開発者が使うことができる便利な機能 5

Slide 6

Slide 6 text

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でやり取り

Slide 7

Slide 7 text

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パース処理によるオーバーヘッド ⾮同期処理によるパフォーマンスへの影響

Slide 8

Slide 8 text

HOW GOOD FRIENDS FOOD JavaScript InterfaceとTurboModule

Slide 9

Slide 9 text

HOW GOOD FRIENDS FOOD JavaScript Interface(JSI)とは • JavaScriptからC++のメソッドを直接呼び出すことができるインタフェース • C++で実装されたオブジェクトのリファレンスをJavaScriptに定義する • Native(objC/Java/C++)のコードをブリッジコードを必要とせずJSから同期的 に呼び出し、処理できる 9

Slide 10

Slide 10 text

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するモジュールがある

Slide 11

Slide 11 text

HOW GOOD FRIENDS FOOD TurboModuleのFAQ

Slide 12

Slide 12 text

HOW GOOD FRIENDS FOOD Q1. TurboModuleは現状使える? • Yes、だけど⼤変 • Native ModuleとJSIをバインドするC++コードは現時点の最新バージョン 0.64.xでは⾃前で書く必要がある • Facebook の React Native チームがFlow-Typeの型情報に基づいてバインド コードを⾃動⽣成する仕組みを実装中(2020年12⽉現在) 12

Slide 13

Slide 13 text

HOW GOOD FRIENDS FOOD Q2. TurboModule対応は必要? • アプリ開発者 • 基本的に不要なはず • ⾃動⽣成されるC++コードをビルドするために追加の設定はいるかも • ライブラリ開発者 • JSIを⽣成するためにJSの型をFlowやTypeScriptで定義する必要がある 13 Ref: https://github.com/react-native-community/discussions-and-proposals/issues/195

Slide 14

Slide 14 text

HOW GOOD FRIENDS FOOD Q3. TurboModuleの実装例は? • React Native Reanimated v2 • 宣⾔的にアニメーションを表現できるライブラリ • RN 0.62.x 以上をサポート 14 • React Native プロジェクトの sample • `packages/rn-tester/js/examples/TurboModule`配下 • 引数で与えられた値を返すだけのモジュール

Slide 15

Slide 15 text

HOW GOOD FRIENDS FOOD (おまけ)TurboModuleを使った パフォーマンス改善 on Android

Slide 16

Slide 16 text

HOW GOOD FRIENDS FOOD TurboModuleを使った起動時間の短縮? • TurboReactPackageはTurboModuleで使われるモジュールパッケージクラス • TurboReactPackageは初期化時にコンストラクタや無名クラスを⽣成しない • RNBridgeにNative Moduleを直接渡している • v0.61からReact Native⾃体のモジュール初期化に使われている • auto-linkされてないNative Moduleで使えば起動の⾼速化が⾒込める…!? 16

Slide 17

Slide 17 text

HOW GOOD FRIENDS FOOD TurboReactPackageの導⼊ステップ • TurboReactPackageを継承したクラスを作る • getModule, createViewManager, getReactModuleInfoProviderを実装する 17 JSでrequireする名前

Slide 18

Slide 18 text

HOW GOOD FRIENDS FOOD 検証 • auto-linkされてない10個のNative ModuleをTurboModule化 • releaseビルドのTTI(Time To Interact)をReactMarkerで3回計測した平均 18 Start モジュール読み込み完了 〜 使⽤端末: Samsung A10e (Android 9)

Slide 19

Slide 19 text

HOW GOOD FRIENDS FOOD 結果 • ほぼ差なし! • コンストラクタで重い初期化処理を実⾏している場合、NativeModule数が更に多ければ結 果は変わるかも 19 TurboReactPackage ReactPackage

Slide 20

Slide 20 text

HOW GOOD FRIENDS FOOD まとめ • TurboModuleはJavaScriptとC++をバインドするJSIによって実現される • Native APIへのアクセスのオーバーヘッドを解消し、起動時間の⾼速化やイン タラクションのパフォーマンスを改善する • RN v0.61.0以上でTurboModuleが部分的に適⽤されているのでパフォーマン ス改善が期待できる 20