Zenn
Open8

React Nativeで気になること色々調査

tokitoki

New Architecture

ここに内容まとめてたけど、折角なので記事に移行した。
https://zenn.dev/toki_dev/articles/0ead165c91968c

出来るだけ、勉強して回答するのでなんでもコメントください🙇
間違ってるところあれば教えて頂けるととても助かります🙇

tokitoki

同期レイアウト

Old Architectureは非同期、New Architecutreは同期について、About the New Architecture の「Example: Rendering a Tooltip」が分かりやすい

Old Architectureではビューの情報をもとに計算して表示する場合に、計算元のビューの描画後に計算が終わって適応される場合がありズレが発生する可能性あり

tokitoki

Fabric: 同時実行レンダラー

React Nativeの新しいレンダリングシステム
従来のレンダリングシステムの概念的な進化
C++でレンダリングロジック統合

New Architectureでは、React 18以降もサポート可能
concurrent renderingとかがサポート可能になる
Suspence, Transitionsとか使える

Transitionなどが使えるので、UI更新の優先度を表現できるようになる

レンダリング→コミット→マウントの3つのフェーズでホストビュー(IOS,Androidなど)に描画

  • レンダリング

    • C++でReact Shadow Treeを作成
      • React Host Componentsに対してのみ発生
      • React Composite Componentsに対しては発生しない
  • コミット

    • レイアウト計算とツリー プロモーションの2つ
    • レイアウト計算
      • 各React Shadow Nodeの位置とサイズを計算
      • Yogaで計算
        • (React Shadow NodeのスタイルとReact Shadow Treeのルートのレイアウト制約が必要?)
    • ツリープロモーション (新しいツリー → 次のツリー)
      • React Shadow Treeを「次のツリー」にする (次のツリーがマウントされるやつ)
    • 補足
      • レイアウトの計算の大部分はC++内でできるが、一部のコンポーネントの計算はネイティブの情報が必要
      • 例: Textのサイズと位置など
      • Yogaはホストプラットフォーム側で定義された関数を呼び出して計算に使う
  • マウント

    • React Shadow TreeをHost View Treeに変換
      • ネイティブにレンダリングされるサイズや位置が構成される
    • C++で差分計算される → 結果はホストビューで実行する変更操作のリスト
      • ビューのフラット化もする (不要なホストビューが作成されないように)
    • ツリープロモーション:
      • 次のマウントフェーズで差分計算ができるように、コミットで設定した「次のツリー」を「以前にレンダリングされたツリー」にする
    • ホストビューに変更操作を実施する
  • 補足:

    • UIスレッドで同期実行:
      • コミットがバックグラウンドスレッドで実行される場合は、マウントフェーズは次のtickにスケジュールされる
      • コミットがUIスレッドで実行される場合は、同じスレッドでマウントまで同期的に実行する

Old Architectureでは、Reract Shadow Tree、レイアウトロジック、View Flatteingが、プラットフォーム毎に実装されていたが、今はC++で実装を共有している

スレッドはUIスレッドとJavaScriptスレッドがあって、ホストビューの操作(Mount)はUIスレッドでしかできない。他(Event, Render, Layout, Commit)はJSスレッドでもどっちでも出来る。
https://reactnative.dev/architecture/threading-model

(シャドウスレッドもあるから3つか)

tokitoki

JSI

JavaScript が C++ オブジェクトへの参照を保持できるようにするインターフェイスであり、その逆も可能。JSIを介して、直接メソッドを呼び出すこともできる。
Old Architecutreで行なっているブリッジが不要になるので、JSONのシリアライズコストがなくなる

C++にJavaScriptをエンジンを埋め込む軽量API。Fabricはこれを使用して、FabricのC++コアとReact間の通信を行う

JNI(Javaネイティブインターフェース)というのもある。JNIはFabricのC++コアとAndroid間の通信に使用されるJabaネイティブメソッドを記述するためのAPI (ISOは??)

tokitoki

TurboModules

古いネイティブモジュールが大幅に改善されたもの

古い方では、JavaScriptで使用されるすべてのネイティブモジュールをアプリ開く時に初期化する必要がある。TurboModulesでは必要な時に各モジュールを読み込める。
例: 4ページ目でカメラモジュールが必要な場合、アプリ起動時に読み込まなくても良くなる。
結果、アプリの起動時間が大幅に改善。

  • ネイティブモジュール
    • ネイティブプラットフォーム言語で記述され、JavaScriptから呼び出せるネイティブコードの一部
  • ネイティブモジュールシステム
    • JavaScriptとネイティブモジュールが相互に通信するためのシステム
  • 古いネイティブモジュールシステム
    • ブリッジベースのネイティブモジュールシステム
  • 新しいネイティブモジュールシステム
    • JSIを利用するネイティブモジュールシステム
tokitoki

Codegen

TypeScriptからインターフェースを作成するのに役立つツール
C++は強い型付け、TypeScriptは強い型付けではないので、間のインターフェースが必要

ビルド時に利用されるもの

tokitoki

Hermes

以下の3つの改善

  • アプリのサイズ改善
  • メモリ使用量の改善
  • アプリ起動時間の改善

Hermesでは、Hermesによって直接実行できるバイトコードをビルド時に作る
Old Architectureでよく使われていたJSCなどは実行時にコンパイル(バイトコード生成)して実行する

Static Hermesも進んでる。
https://github.com/facebook/react-native/pull/48531

tokitoki

Yoga
Web 開発の CSS 標準である Flex ボックスを実装するクロスプラットフォーム レイアウト エンジン

Yoga は、主に Flexbox に重点を置いた、使い慣れた CSS のサブセットをサポート。
ネイティブ プラットフォームとブラウザー間でコードを共有できる。
Yoga は C++ で書かれている。

ログインするとコメントできます