React NativeにおけるFabric—その定義、レンダリングアーキテクチャと仕組み

著者: IT Sectr 公開日: 2026-06-04 読了時間: 10 分

FabricはReact Nativeの新しいレンダラーで、C++で完全に書き換えられ、JSIと統合されています。UIViewヤViewManagerに基づく古いレンダリングを置き換え、Shadow Treeを通じて同期的なUI更新と効率的な変更計算を実現します。Meta Engineering Blog, 2024によると、Fabricは新アーキテクチャの必須コンポーネントであり、React Native 0.76+で利用可能です。

ポイント

  • Fabric—古いUIViewレンダリングを置き換える、React Native向けの新しいC++レンダラー。
  • Shadow Tree—変更を効率的に計算できる、不変のノードのツリー。
  • 同期性—FabricはBridgeの非同期キューなしで、UIを同期的にレンダリングします。
  • 速度—Fabricは再描画回数を減らし、描画を2–3倍高速化します。
  • 統合—FabricはJSIを通じて動作し、iOSとAndroidのための統一C++レイヤーを提供します。

Fabricとは?

FabricはReact Nativeの新しいレンダリングシステムで、Shadow ThreadヤBridgeを通じて動作する古いレンダラーを置き換えました。古いアーキテクチャでは、レンダリングプロセスには3つのステップがありました:JavaScriptがVirtual DOMを計算し、Shadow Thread (Yoga)がレイアウトを計算し、Native ThreadがUIViewを描画します。Fabricはこれらのすべてのステップを、同期的に動作する単一のC++パイプラインに統合します。

Fabricの開発は2019年、Lean Coreイニシアチブおよび「The New Architecture」プロジェクトの一环として始まりました。主な目的は、非同期三段階レンダリングに伴うパフォーマンス問題を解決することでした。古いアーキテクチャでは、状態変更ごとに異なるスレッドを経由する3回のパスが必要で、データ変更からUIレンダリングまでに邅延が生じました。

Fabricは不変Shadow Tree (Immutable Shadow Tree)のコンセプトに基づいています。ツリーの各ノードは、propsヤ状態を持つReactコンポーネントを表します。状態が変わると新しいツリーが作られ、Fabricは古いツリーと新しいツリーの違いを計算し、必要な変更のみをネイティブUIに適用します。これによりUIView/ViewGroup操作が最小限に抑えられ、レンダリング時間が短縮されます。

Shadow Treeの仕組み

Shadow TreeはFabric動作の基盤です。Shadow TreeがC++側にのみ存在し、非同期Bridgeを通じてJSツリーから分離されていた古いアーキテクチャとは異なり、Fabricは完全に同期された階層的UI表現を作ります。Shadow Treeのノードはコンポーネントのprops、状態、スタイルを保持し、YogaがC++レベルで直接レイアウトを計算します。

Reactコンポーネントが状態を更新すると、React Nativeは新しいShadow NodeをFabricに送信します。FabricはUI全体を再レンダリングせず、C++レベルでディフィングアルゴリズムを使用して、変更のあったノードを特定します。変更のあったノードのみがネイティブレンダリングに送られるため、処理量が大幅に減少します。

Fabricの4段階レンダリング

Fabricにおけるレンダリングプロセスは3つのフェーズからなり、スレッドスイッチングなしでC++レベルで同期的に実行されます。第1フェーズはRender:Reactがコンポーネントのレンダラー関数を呼び出し、React Element Treeを返します。第2フェーズはCommit:React Nativeが新しいShadow Treeを作成し、古いバージョンに基づいて変更を計算します。第3フェーズはMount:FabricがネイティブUIに変更を適用し、UIViewsを作成・更新・削除します。

  • Render—JSスレッドで実行、React Element Treeを作成。
  • Commit—C++ Shadow Treeがディフを計算し、変更リストを作成。
  • Mount—メインスレッドでネイティブUIに変更を適用。

3つのフェーズは単一のパイプラインとして動作し、データはシリアライゼーションなしでJSIを通じて伝達されます。これが、フェーズ間にギャップがあった古いアーキテクチャとの大きな違いです:JS → (JSON) → Shadow Thread → (レイアウト) → Native Thread。

Fabric vs古いレンダラー:比較

Fabricと古いレンダラーの比較により、React Nativeアーキテクチャがどれほど大きく変わったかがわかります。古いレンダラーは非同期的に動作し、レンダリングプロセスを独立した3つのスレッドに分けていました。Fabricはすべてを単一のC++パイプラインに統合します。

特徴古いレンダラーFabric
アーキテクチャ3スレッド (JS, Shadow, Native)単一C++パイプライン
同期性非同期レンダリング同期レンダリング
Shadow Tree可変、スレッドごとに独自のコピー不変、統一
チャネルBridge + JSONシリアライゼーションJSI + 直接C++コール
パフォーマンス1フレーム当たり16msまでの遅延1フレーム当たり1ms未満の遅延

実際には、FabricはUI更新が頻繁に行われるアプリケーション(アニメーション、浮き上がりヘッダー付きスクロール、リアルタイムデータ)で特に効果的です。静的なページ(テキストやボタン)では違いはあまり目立ちません。Metaのベンチマークによると、Fabricはリストの初回レンダリング時間を40–60%減少します。

JSIとFabric:新たなコミュニケーション

JSI (JavaScript Interface)は、Fabricを可能にする重要なコンポーネントです。JSIを通じて、FabricはシリアライゼーションなしでJavaScript値に直接アクセスできます。ReactがFabricにpropsを渡す際、JSONを経由してコピーされるのではなく、JSIがJSエンジンのメモリー上のデータへのポインターを渡します。

JSIアーキテクチャにより、FabricはいかなるJavaScriptエンジン(Hermes、JSC、V8)でも動作できます。FabricのC++コードは特定のJSエンジン実装に依存しないため、保守性が高く、テストが簡素です。すべてのUI操作(作成、更新、削除)はJSIを通じて実行され、最小限のラテンシーを保証します。

cpp
// JSIを通じたabric C++レンダリングパイプライン
void mountShadowNode(
    jsi::Runtime& runtime,
    const ShadowNode::Shared& shadowNode,
    const ShadowNode::SharedList& children
) {
    auto props = shadowNode->getProps();
    auto state = shadowNode->getState();

    // JSIを通じた同期的なprop伝達
    jsiValue.asObject(runtime)
        .getProperty(runtime, "style")
        .asObject(runtime);

    // Yogaを通じた直接レイアウト計算
    auto layoutMetrics =
        YogaLayoutableShadowNode::layout(children);

    // ネイティブUIに変更を適用
    UIManager::synchronouslyUpdateViewOnUIThread(
        shadowNode->getTag(), layoutMetrics
    );
}

主な利点は同期更新です。古いアーキテクチャでは、UIは非同期キューを通じて更新されていました:ReactがBridgeを通じてコマンドを送信し、Shadow Threadがレイアウトを処理し、Native Threadがレンダリングします。Fabricでは、すべてのステップが一つのパスで順次実行されます。これによりレースコンディションが解消され、UIがアプリケーションの現在の状態と一致することが保証されます。

Fabricへの移行

Fabricへの移行にはReactコンポーネントの書き換えは不要で、現行のReact Nativeコンポーネントはすべて続けて動作します。ただし、ネイティブコード(Native Module、カスタムViewManager)を使用するライブラリは更新が必要になる場合があります。Metaは新アーキテクチャを有効にする前に、各ライブラリの互換性を確認することを推奨しています。

React Native 0.76+プロジェクトでFabricを有効にするには、react-native.config.jsでnewArchEnabled: trueフラグを設定します。FabricはTurbo Moduleと一緒に自動的に有効になります。問題が発生した場合は、アプリケーションコードを変更せずに古いレンダラーに戻すことでFabricを無効にできます—両アーキテクチャは並行対応されています。

js
// package.json — Fabric互換ライブラリを確認
"react-native": "0.76.6",
"react-native-safe-area-context": "^5.0.0",
"react-native-screens": "^4.0.0",
"react-native-reanimated": "^3.16.0",
"react-native-gesture-handler": "^2.21.0"

移行時には、すべてのネイティブライブラリをFabricに互換性のあるバージョンに更新することが重要です。react-native-reanimatedやreact-native-gesture-handlerのような主要ライブラリはすでに新アーキテクチャをサポートしています。まだ更新されていないライブラリについては、Fabricが互換メカニズムを提供しており、ライブラリがFabricをサポートしていない場合は、レンダラーが自動的に古いものにフォールバックします。

よくある質問

FabricはReact Native Expoで利用可能ですか?

はい、Expo SDK 52以降、新アーキテクチャはデフォルトで有効になります。FabricやTurbo Modulesは追加設定なしでmanaged workflowで利用可能です。

Fabricはアニメーションのパフォーマンスを向上させますか?

Fabricは同期レンダリングによりアニメーションを大幅に向上させます。JSスレッド上のアニメーションがBridgeのメッセージ処理と競合しなくなるため、カチカチやFPS低下が解消されます。

FabricのためにUIコンポーネントを書き換える必要がありますか?

いいえ、標準のReact Nativeコンポーネントはすべて変更なしでFabricで動作します。カスタムのViewManagerコンポーネントのみ、新アーキテクチャをサポートするために更新が必要です。

Fabricを無効にして古いレンダラーに戻すにはどうすればいいですか?

react-native.config.jsでnewArchEnabled: falseを設定し、アプリを再ビルドします。すべてのモジュールヤコンポーネントは変更なしで動作を続けます—Fabricと古いレンダラーは完全に互換可能です。

React Nativeのブリッジレスモードとは?

ブリッジレスモードは、Bridgeが完全に無効になったFabricの動作モードです。すべてのコミュニケーションがJSIのみを経由するため、最大のパフォーマンスを実現します。React Native 0.76+で利用可能です。

まとめ

  • Fabric—単一のパイプラインでレイアウト計算とUIレンダリングを統合する、新しいC++ React Nativeレンダラー。
  • Shadow Tree—全体再レンダリングなしで効率的な変更計算を可能にする、不変のシャドウノードのツリー。
  • 同期性—Fabricは古いアーキテクチャの非同期レンダリングに伴う遅延を解消します。
  • JSI—FabricはJSONシリアライゼーションなしのデータ伝送のために直接のC++インタフェースを使用します。
  • 互換性—Fabricは新アーキテクチャを持たないライブラリに対して、古いレンダラーとの並行動作をサポートします。
  • パフォーマンス—リストのレンダリング時間が40–60%減少し、アニメーションがより滑らかに動作します。
  • 移行—newArchEnabledフラグによるFabricの有効化、最大パフォーマンスのためのブリッジレスモードサポート。

ターンキー方式のモバイルアプリケーションを開発します

IT Sectrは2017年からスタートアップや企業向けにiOS・Androidアプリケーションを開発しています。私たちがご相談に乗り、最適なソリューションをご提案します。

プロジェクトについて相談

こちらもお読みください