React Nativeでアプリを開発していると、「ネイティブとの通信が遅い」「レイアウトがちらつく」「起動に時間がかかる」といった課題に直面することがあります。これらの問題の多くは、旧アーキテクチャの非同期Bridge設計に起因していました。
2018年にMeta(旧Facebook)が再設計を開始し、2024年にv0.76でデフォルト化、2025年10月のv0.82でLegacy Architectureが完全に廃止、そして2026年2月のv0.84ではHermes V1がデフォルトJSエンジンとなりました。現在のReact Nativeプロジェクトはすべてこの新しい設計で動作します。
旧アーキテクチャ(Bridge)が抱えていた3つの制約
New Architectureの設計意図を正しく理解するには、まず旧アーキテクチャの課題を把握する必要があります。
非同期シリアライゼーションによる通信遅延
旧アーキテクチャでは、JavaScriptスレッドとネイティブスレッドの間にBridgeと呼ばれる非同期メッセージキューが存在していました。JS側で生成されたUI命令やネイティブモジュール呼び出しは、すべてJSON形式にシリアライズされ、Bridgeを経由してネイティブ側に渡されていました。
この設計には以下の問題がありました。
- JSON変換のオーバーヘッドが通信のたびに発生する
- 非同期通信のため、レイアウト計測結果を同一フレーム内で反映できない
- 大量のデータ(例: カメラのフレームバッファ)を効率よく受け渡せない
レイアウト計測の非同期性
旧アーキテクチャでは onLayout コールバック内でUIの位置やサイズを取得しても、その結果をもとにした再描画が別フレームで処理される可能性がありました。ツールチップの配置やドロップダウンの表示位置といった「計測→即反映」が求められるUIで、ちらつきやジャンプが発生する原因でした。
全モジュールの一括初期化
旧NativeModulesは、アプリ起動時にすべてのモジュールが一括で初期化されていました。実際には利用しないモジュールも含めて初期化されるため、起動時間に無視できない影響を与えていました。
New Architectureを構成する4つの柱
New Architectureは、上記の課題を根本から解消するためにJSI・Fabric・Turbo Native Modules・Codegenの4つの要素で構成されています。
JSI(JavaScript Interface)― Bridgeなしの直接通信
JSIはNew Architectureの中核にあたるC++レイヤーです。従来のBridgeを置き換え、JavaScriptとネイティブコードがメモリ参照を通じて直接やり取りできるようにします。
旧Bridge方式とJSIの通信フローの違い
| 項目 | 旧Bridge | JSI |
|---|---|---|
| 通信方式 | 非同期メッセージキュー | 同期・非同期の両方に対応 |
| データ形式 | JSON シリアライゼーション | C++オブジェクトへの直接参照 |
| 呼び出しコスト | シリアライズ+デシリアライズ | 参照経由のメソッド呼び出し |
| 大容量データ | 実質的に不可能 | メモリ共有で高速処理 |
| JSエンジン依存 | JavaScriptCoreに固定 | 任意のエンジン(Hermes等)に対応 |
JSIの仕組みを簡潔に整理すると、JavaScriptオブジェクトがC++のHost Objectへの参照を保持し、C++側もJavaScriptオブジェクトの参照を保持できる双方向バインディングです。これにより、データのコピーやシリアライゼーションなしに関数呼び出しやデータ受け渡しが実現されます。
この設計によって、たとえばカメラアプリでフレームバッファ(1フレームあたり約10MB〜30MB)をリアルタイムにJS側で処理するといった、旧Bridgeでは不可能だったユースケースが実現されました(出典: React Native公式)。
Fabric ― C++ベースの新レンダリングシステム
FabricはReact Nativeの新しいUIレンダラーです。旧UIManagerを置き換え、C++で実装されたShadow Treeを中心としたレンダリングパイプラインを提供します。
Fabricの主なメリット
- 同期レイアウト計算:
useLayoutEffectで要素の位置・サイズを計測し、同一フレーム内で反映できます。ツールチップやポップオーバーのちらつきが解消されます - Concurrent Renderer対応: React 18以降のSuspense、Transitions、自動バッチングといった機能がReact Nativeでも利用可能になりました
- クロスプラットフォーム実装: C++で共通のレンダリングロジックが実装されているため、iOS/Android間での描画の一貫性が向上しています
- View Flattening: 不要な中間Viewノードを自動で平坦化し、描画パフォーマンスを改善します。典型的なShadow Treeは600〜1,000ノードですが、フラッテン後は約200ノードまで削減されます
以下は、旧アーキテクチャとFabricでのツールチップ実装の比較です。
旧アーキテクチャ(非同期レイアウト):
function ViewWithTooltip() {
// onLayoutの計測結果が次フレーム以降に反映され、ちらつきが発生
const onLayout = React.useCallback(event => {
targetRef.current?.measureInWindow((x, y, width, height) => {
setTargetRect({ x, y, width, height });
});
}, []);
return (
<>
<View ref={targetRef} onLayout={onLayout}>
<Text>コンテンツ</Text>
</View>
<Tooltip targetRect={targetRect} />
</>
);
}
Fabric(同期レイアウト):
function ViewWithTooltip() {
// useLayoutEffectにより計測と反映が同一コミットで実行される
useLayoutEffect(() => {
targetRef.current?.measureInWindow((x, y, width, height) => {
setTargetRect({ x, y, width, height });
});
}, [setTargetRect]);
return (
<>
<View ref={targetRef}>
<Text>コンテンツ</Text>
</View>
<Tooltip targetRect={targetRect} />
</>
);
}
Turbo Native Modules ― 型安全で遅延ロード対応のモジュールシステム
Turbo Native Modulesは、旧NativeModulesを置き換える新しいネイティブモジュールの仕組みです。JSIの上に構築されており、以下の特徴があります。
- 遅延ロード(Lazy Loading): モジュールは実際に呼び出された時点で初期化されます。起動時に全モジュールを一括初期化していた旧方式と比べ、アプリの起動速度が改善されます
- 型安全なインターフェース: TypeScriptまたはFlowで定義したSpecファイルをもとにCodegenがネイティブ側のインターフェースを自動生成します。JSとネイティブの型不整合がビルド時に検出されます
- 同期・非同期の両対応: JSIの恩恵により、同期的な戻り値を持つ関数と、Promiseを返す非同期関数の両方を定義できます
旧NativeModulesとTurbo Native Modulesの比較
| 特性 | 旧NativeModules | Turbo Native Modules |
|---|---|---|
| 通信経路 | Bridge(JSON) | JSI(直接参照) |
| 型検査 | なし(実行時エラー) | Codegen生成(ビルド時検査) |
| モジュール初期化 | 起動時に全モジュール一括 | 利用時に遅延ロード |
| 同期呼び出し | 不可 | 対応 |
| コード生成 | 手動実装 | Codegenで自動生成 |
Turbo Native Moduleの実装例
まず、TypeScriptでSpecファイル(モジュールのインターフェース定義)を作成します。
// specs/NativeLocalStorage.ts
import type { TurboModule } from 'react-native';
import { TurboModuleRegistry } from 'react-native';
export interface Spec extends TurboModule {
setItem(value: string, key: string): void;
getItem(key: string): string | null;
removeItem(key: string): void;
clear(): void;
}
export default TurboModuleRegistry.getEnforcing<Spec>(
'NativeLocalStorage',
);
ファイル名のプレフィックスは Native が必須です。このSpecをもとにCodegenがAndroid(Kotlin/Java)およびiOS(Objective-C++)のインターフェースコードを生成します。
JS側からの呼び出しは以下のようになります。
import NativeLocalStorage from './specs/NativeLocalStorage';
// 値の保存
NativeLocalStorage.setItem('保存したい値', 'myKey');
// 値の取得(同期呼び出し)
const value = NativeLocalStorage.getItem('myKey');
Codegen ― 型定義からネイティブコードを自動生成
CodegenはNew Architectureの型安全性を担保するビルドツールです。TypeScriptまたはFlowで記述したSpecファイルを入力とし、C++・Kotlin/Java・Objective-C のインターフェースコードを自動生成します。
Codegenの処理フロー
- 開発者がTypeScript/FlowでSpecファイルを記述
- ビルド時にCodegenがSpecを解析
- 各プラットフォーム向けのインターフェースコード(抽象クラス・プロトコル)を生成
- 開発者は生成されたインターフェースを継承してネイティブ実装を記述
Codegenの設定は package.json に記述します。
{
"codegenConfig": {
"name": "NativeLocalStorageSpec",
"type": "modules",
"jsSrcsDir": "specs",
"android": {
"javaPackageName": "com.nativelocalstorage"
}
}
}
Codegenの実行はビルド時に自動で行われるため、通常は手動で実行する必要はありません。必要に応じて以下のコマンドで明示的に実行できます。
# Android
cd android && ./gradlew generateCodegenArtifactsFromSchema
# iOS
cd ios && bundle exec pod install
Bridgeless Mode ― Bridgeの完全排除
New Architectureの最終形態がBridgeless Modeです。JSI・Fabric・Turbo Native Modulesの3つが揃うことで、旧BridgeのMessageQueueが完全に不要になります。
React Native 0.82以降はBridgelessが唯一の動作モードです。旧Bridgeのコードパスは存在しないため、「Bridgeless Modeを有効化する」という操作自体が不要になりました。
Bridgeless化によるメリット
- MessageQueueの廃止によりメモリ使用量が削減
- JSON変換処理がなくなり通信レイテンシが低減
- JSエンジンの切り替えが容易(Hermes、V8、JavaScriptCoreなど)
パフォーマンス実測データ ― 旧アーキテクチャとの比較
Amazon App Storeチームが実施したベンチマークでは、MovieCardコンポーネントを1,500回レンダリングする負荷テストで新旧アーキテクチャを比較しています(出典: Amazon Developer Blog)。
デバイス別のレンダリング性能改善幅
| テスト環境 | New Architectureによる改善幅 |
|---|---|
| Android TVエミュレータ(1080p, Android 14) | 約500ms高速化 |
| Fire HD Plusタブレット(第10世代) | 約900ms高速化 |
| Fire TV Stick HD | 約1,000ms高速化 |
低スペックなデバイスほど改善幅が大きい傾向があります。パフォーマンスの改善度合いはアプリの設計やネイティブモジュールの使用頻度によっても異なります。
React Native Working Groupによる、コンポーネントレンダリング性能の詳細なベンチマーク結果もあります(出典: React Native WG Discussion #123)。
iPhone 12 Pro(iOS)でのレンダリング性能比較
| レンダリング対象 | 旧アーキテクチャ | New Architecture | 改善率 |
|---|---|---|---|
| View × 1,500 | 137ms | 117ms | 約15% |
| View × 5,000 | 435ms | 266ms | 約39% |
| Text × 1,500 | 324ms | 284ms | 約13% |
| Text × 5,000 | 1,009ms | 808ms | 約20% |
| Image × 5,000 | 673ms | 451ms | 約33% |
iOSでは特にView描画で大きな改善が見られ、5,000 Viewレンダリングでは約39%の高速化が計測されています。
さらに、React Native 0.82で導入されたHermes V1(実験的)を有効にすると、追加のパフォーマンス改善が報告されています(出典: React Native公式ブログ)。
Hermes V1のパフォーマンス改善(Expensifyアプリでの計測)
| 計測項目 | Android(低スペック端末) | iOS |
|---|---|---|
| バンドルロード時間 | 3.2%高速化 | 9%高速化 |
| Total TTI | 7.6%高速化 | 2.5%高速化 |
| Content TTI | 7.2%高速化 | 7.5%高速化 |
React Native 0.82 ― Legacy Architecture廃止とその影響
2025年10月にリリースされたReact Native 0.82は、New Architecture Onlyとなった最初のバージョンです。旧BridgeベースのLegacy Architectureは完全に廃止されました(出典: React Native公式ブログ)。
0.82の主な変更点
- Legacy Architecture削除:
newArchEnabled=false(Android)やRCT_NEW_ARCH_ENABLED=0(iOS)の設定は無視されます - Hermes V1(実験的): AOTコンパイルを見据えた新しいJSエンジンバージョン
- React 19.1.1対応: Owner Stacksの完全サポート、Suspense Boundaryの修正
- DOM Node APIs: Web互換のDOM APIがネイティブコンポーネントで利用可能
- Web Performance APIs(Canary):
performance.now()、PerformanceObserver、Event Timing APIなど - Android debugOptimizedビルド: デバッグ中でもC++最適化を適用し、約60FPSの動作を実現(通常のdebugビルドは約20FPS)
Interop Layer(互換レイヤー)について
旧NativeModulesやNative Componentを使用しているサードパーティライブラリのために、Interop Layerが引き続き提供されています。このレイヤーにより、まだTurbo Native ModulesやFabric Componentに移行していないライブラリもNew Architecture上で動作可能です。ただし、Interop Layerは将来的に削除される予定のため、早期の移行が推奨されています。
Old ArchitectureからNew Architectureへの移行手順
バージョン別の移行戦略
| React Nativeバージョン | New Architectureの状態 | 推奨アクション |
|---|---|---|
| 0.68〜0.75 | オプトイン(実験的) | まず0.76以上への更新を推奨 |
| 0.76〜0.81 | デフォルト有効(無効化可能) | New Architectureで動作確認 |
| 0.82以降 | 唯一のアーキテクチャ | Legacy Architectureは存在しない |
推奨される移行ステップ
Step 1: 依存ライブラリの互換性確認
React Native Directory でプロジェクトが使用しているライブラリのNew Architecture対応状況を確認します。
Step 2: 0.81でNew Architectureを有効化してテスト
0.81は旧・新両方のアーキテクチャに対応する最後のバージョンです。まずこのバージョンでNew Architectureを有効にし、動作を検証します。
# android/gradle.properties
newArchEnabled=true
# ios/Podfile
ENV['RCT_NEW_ARCH_ENABLED'] = '1'
Step 3: カスタムNativeModulesの移行
自前のNativeModulesがある場合、Turbo Native Modulesへ書き換えます。Interop Layerが暫定的に互換性を提供しますが、本格的な移行が推奨されます。
Step 4: 0.82へアップグレード
動作確認が完了したら0.82(またはそれ以降)にアップグレードします。
# Upgrade Helperを活用
# https://react-native-community.github.io/upgrade-helper/
Expoプロジェクトの場合
ExpoはSDK 52以降でNew Architectureがデフォルト有効です。expo-modules-core がNew Architectureをネイティブサポートしているため、Expo Modulesを使用しているプロジェクトは追加の対応なしで動作します(出典: Expo公式ドキュメント)。
既存のExpoプロジェクトでNew Architectureを無効化する場合は、app.json で設定できます。
{
"expo": {
"newArchEnabled": false
}
}
ただし、Expo SDK 55以降ではNew Architectureが強制有効となり、無効化オプションは削除されています(出典: Expo公式ドキュメント)。
0.83・0.84で進んだNew Architectureの成熟
New Architectureの進化は0.82で止まっていません。後続バージョンでさらなる最適化が進んでいます。
0.83(2025年12月)― 破壊的変更ゼロのリリース
React Native史上初めて破壊的変更のないリリースとなりました。React 19.2の<Activity>コンポーネントやuseEffectEventフック、Web Performance APIsの安定化、IntersectionObserver(Canary)といった機能追加が中心です。また、iOS向けのLegacy Architectureコード除去が実験的に導入され、ビルド時間が20%、アプリサイズが6%削減される効果が確認されています(出典: React Native公式ブログ)。
0.84(2026年2月)― Hermes V1のデフォルト化
0.84ではHermes V1がデフォルトJSエンジンとなりました。0.82では実験的オプトインだったものが、わずか4ヶ月で標準搭載に昇格しています。iOSではLegacy Architectureのコードがデフォルトでビルドから除外され、Androidでも多数のLegacy関連クラスが削除されました。Node.js 22.11以降が必須となっている点にも注意が必要です(出典: React Native公式ブログ)。
React Nativeの今後の方向性
Static Hermesによるさらなる高速化
Hermes V1のデフォルト化は、Static Hermes(AOTコンパイル対応)への布石です。JavaScriptコードを事前にネイティブコードへコンパイルすることで、起動時間とランタイムパフォーマンスの飛躍的な改善が期待されています。JITコンパイルの導入も予定されており、実行時の最適化がさらに進む見込みです。
Web標準との整合性
DOM Node APIsやWeb Performance APIs、IntersectionObserverの導入に見られるように、React NativeはWeb標準APIとの互換性を高める方向で進んでいます。ReactのWeb向けコードとReact Nativeのコード間でのロジック共有がさらに容易になります。
React 19.2と新しいコンポーネントモデル
React 19.2では<Activity>コンポーネント(画面のプリレンダリング)やuseEffectEventフック(イベントハンドラ内でのエフェクト実行)が導入されました。React Nativeはこれらの新APIを積極的に取り込んでおり、Webとモバイルの開発体験の統一が加速しています。
まとめ
React Native New Architectureは、旧Bridgeの制約を解消し、ネイティブアプリと同等のパフォーマンスとUXを目指した再設計です。0.82でLegacy Architectureが廃止され、0.84ではHermes V1がデフォルト化。Legacy Architectureのコード自体もビルドから除外される段階に入りました。
4つの柱を簡潔に振り返ります。
- JSI: JSONシリアライゼーションを排除し、JSとネイティブがC++オブジェクト参照で直接通信
- Fabric: C++ベースの新レンダラー。同期レイアウトとConcurrent Renderingに対応
- Turbo Native Modules: 遅延ロードと型安全なインターフェースを備えた新モジュールシステム
- Codegen: TypeSpec定義からネイティブインターフェースコードを自動生成
移行は段階的に進められます。まず React Native Directory でライブラリの互換性を確認し、0.81でのNew Architecture有効化テストを経て0.82へアップグレードするのが安全な手順です。
公式ドキュメントのNew Architecture解説ページや、React Native New Architecture Working Groupのディスカッションも参考になります。
