2026年のReact Native新アーキテクチャ:Hermes V1、ブリッジレスモードとインタビュー質問

React Nativeの新アーキテクチャを徹底解説。Hermes V1エンジン、ブリッジレスモード、TurboModules、Fabricレンダラーの仕組み、パフォーマンスベンチマーク、移行ガイド、技術面接の質問と回答を網羅。

React Native新アーキテクチャ:Hermes V1、Fabric、TurboModules、ブリッジレスモードの技術解説

React Nativeの新アーキテクチャは2026年に完全な成熟期を迎えました。React Native 0.84ではHermes V1がデフォルトエンジンとして採用され、0.85ではレガシーブリッジのコードがすべて削除されました。開発者はアーキテクチャフラグや互換性レイヤーを意識することなく、ネイティブに匹敵するパフォーマンスを得られるようになっています。

新アーキテクチャ(Fabric + TurboModules + ブリッジレスモード + Hermes V1)はもはやオプトインではありません。React Native 0.84以降のすべてのプロジェクトでデフォルトとして使用されます。既存のコードベースからレガシーブリッジのコードを削除する必要があります。

React Nativeアーキテクチャスタックの変遷

旧来のReact Nativeアーキテクチャは、JavaScriptとネイティブコード間のメッセージ受け渡しにシングルスレッドの非同期JSONブリッジに依存していました。タッチイベント、レイアウト計算、モジュール呼び出しなど、すべてのインタラクションがこのボトルネックを通過していたのです。新アーキテクチャでは、このパイプラインの各レイヤーを、直接的かつ同期的な代替手段に置き換えています。

| レイヤー | 旧アーキテクチャ | 新アーキテクチャ | |---------|-----------------|------------------| | JSエンジン | JavaScriptCore | Hermes V1(バイトコード + JIT) | | レンダラー | Paper(非同期ブリッジ) | Fabric(同期、共有C++) | | ネイティブモジュール | ブリッジモジュール(JSONシリアライズ) | TurboModules(JSI、直接呼び出し) | | 通信 | 非同期JSONブリッジ | JSI(JavaScript Interface) | | 初期化 | ブリッジ初期化 + モジュール登録 | ブリッジレス(遅延、オンデマンド) |

JSI(JavaScript Interface)がその基盤となっています。すべての呼び出しをJSONにシリアライズしてキューに渡す代わりに、JSIはC++ホストオブジェクトをJavaScriptに直接公開します。以前はJSONエンコード、ブリッジキューイング、JSONデコードを必要としたTurboModuleの呼び出しが、直接の関数呼び出しとして完了するようになりました。

Hermes V1:デフォルトJavaScriptエンジン

Hermes V1は、2026年2月にリリースされたReact Native 0.84でデフォルトエンジンとなりました。これは以前のHermesバージョンからの段階的なアップデートではなく、コンパイラとVMの完全な書き直しです。

改善は4つの領域にわたります。新しいバイトコード形式を持つ書き直されたコンパイラ、改善されたJITコンパイラ、Hades並行ガベージコレクタ、そしてReact 19で使用されるモダンなJavaScriptパターンへの対応強化です。

HermesV1Benchmarks.jsjavascript
// Comparing startup and runtime metrics

// Hermes V1 bytecode is pre-compiled at build time
// No parse-compile step at runtime = faster cold starts

// Cold start comparison (production build, Pixel 8):
// Hermes V1:  ~850ms TTI
// JSC:        ~1200ms TTI  (29% slower)

// Memory footprint (complex app, 50+ screens):
// Hermes V1:  ~45MB baseline
// JSC:        ~72MB baseline (38% more)

// GC pause comparison (FlatList, 500+ complex cells):
// Hermes V1 (Hades):  <12ms max pause
// Old Hermes:         ~45ms occasional pauses
// Result: zero dropped frames in scroll benchmarks

並行ガベージコレクタであるHadesは、特に注目に値します。以前のHermesバージョンではstop-the-world型のGCを使用しており、リストスクロール中に時折目に見えるジャンクを引き起こしていました。Hadesはバックグラウンドスレッドで並行的にコレクションを実行し、GCポーズを12ms未満に抑えます。複雑なセルを持つ長いリストをレンダリングするアプリにとって、これはJavaScript側のフレームドロップの最後の原因を排除するものです。

Hermes V1は、React Native 0.84でWebAssemblyサポートも導入しました。Rust、C、C++で書かれたパフォーマンスクリティカルなコードをWASMにコンパイルしてアプリ内で実行でき、プラットフォーム固有のバインディングを書くことなく、デバイス上でのAI推論、重い数値計算、既存のネイティブライブラリの再利用が可能になります。

Fabricレンダラー:同期レイアウトとレンダリング

Fabricは、iOSとAndroidで共有されるC++コアを持つレンダラーとしてPaperを置き換えます。決定的な違いは、レイアウト計算がブリッジを介して非同期に行われるのではなく、JavaScriptスレッド上で同期的に実行される点です。

この同期モデルにより、Paperでは不可能だった2つの機能が実現されます。

  1. 並行レンダリングのサポート:FabricはReact 19の並行機能と統合されています。Transitions、Suspenseバウンダリ、useTransitionが正しく動作するのは、Fabricがレンダリングを中断・再開できるためです。

  2. 直接C++レイアウト:Yoga(レイアウトエンジン)がJavaScriptランタイムと同じメモリ空間で実行されます。フレックスボックス計算のシリアライズオーバーヘッドがありません。

FabricConcurrentExample.tsxtypescript
// Concurrent features work correctly with Fabric
import React, { useState, useTransition } from 'react'
import { View, Text, FlatList, TextInput, StyleSheet } from 'react-native'

type Item = { id: string; name: string; category: string }

function SearchableList({ items }: { items: Item[] }) {
  const [query, setQuery] = useState('')
  const [filtered, setFiltered] = useState(items)
  const [isPending, startTransition] = useTransition()

  const handleSearch = (text: string) => {
    setQuery(text) // Urgent: update input immediately
    startTransition(() => {
      // Non-urgent: filter can be deferred
      const result = items.filter(item =>
        item.name.toLowerCase().includes(text.toLowerCase())
      )
      setFiltered(result)
    })
  }

  return (
    <View style={styles.container}>
      <TextInput
        value={query}
        onChangeText={handleSearch}
        placeholder="Search items..."
        style={styles.input}
      />
      {isPending && <Text style={styles.pending}>Filtering...</Text>}
      <FlatList
        data={filtered}
        keyExtractor={item => item.id}
        renderItem={({ item }) => (
          <View style={styles.row}>
            <Text>{item.name}</Text>
          </View>
        )}
      />
    </View>
  )
}

const styles = StyleSheet.create({
  container: { flex: 1, padding: 16 },
  input: { borderWidth: 1, borderColor: '#ccc', padding: 12, marginBottom: 8 },
  pending: { color: '#888', marginBottom: 4 },
  row: { padding: 12, borderBottomWidth: 1, borderBottomColor: '#eee' },
})

この例のuseTransitionフックは、Fabricが重要である理由を示しています。Paperでは、レンダラーが進行中のレンダリングを中断できなかったため、startTransitionは効果がありませんでした。FabricのReact 19並行モードとの統合により、遅延更新が設計通りに機能し、バックグラウンドで数千のアイテムをフィルタリングしながらもテキスト入力の応答性が維持されます。

TurboModulesとJSI:シリアライズオーバーヘッドの排除

TurboModulesは従来のNativeModulesシステムを置き換えるものです。パフォーマンスの差は、JSONシリアライズの完全な排除から生まれます。ブリッジモジュールの呼び出しは次の経路をたどっていました:JSオブジェクト → JSON.stringify → ブリッジキュー → JSON.parse → ネイティブ呼び出し → JSON.stringify → ブリッジキュー → JSON.parse → JSコールバック。TurboModuleの呼び出しは、JSIを通じた直接的なC++関数呼び出しです。

NativeDeviceInfo.tstypescript
// TurboModule spec using the Codegen
import type { TurboModule } from 'react-native'
import { TurboModuleRegistry } from 'react-native'

export interface Spec extends TurboModule {
  // Synchronous: returns immediately, no bridge round-trip
  getDeviceModel(): string
  getOSVersion(): string
  getBatteryLevel(): number

  // Asynchronous: for operations that genuinely need async
  getStorageUsage(): Promise<{ used: number; total: number }>
}

export default TurboModuleRegistry.getEnforcing<Spec>('DeviceInfo')
DeviceInfoModule.ktkotlin
// Native Android implementation of the TurboModule
package com.app.modules

import com.facebook.react.bridge.ReactApplicationContext
import com.facebook.react.bridge.ReadableMap
import com.facebook.react.bridge.WritableNativeMap
import com.facebook.react.module.annotations.ReactModule

@ReactModule(name = "DeviceInfo")
class DeviceInfoModule(reactContext: ReactApplicationContext) :
  NativeDeviceInfoSpec(reactContext) {

  // Synchronous via JSI - no bridge, no JSON, no queue
  override fun getDeviceModel(): String {
    return android.os.Build.MODEL
  }

  override fun getOSVersion(): String {
    return "Android ${android.os.Build.VERSION.RELEASE}"
  }

  override fun getBatteryLevel(): Double {
    val manager = reactApplicationContext
      .getSystemService(android.content.Context.BATTERY_SERVICE)
      as android.os.BatteryManager
    return manager.getIntProperty(
      android.os.BatteryManager.BATTERY_PROPERTY_CAPACITY
    ).toDouble()
  }

  override fun getStorageUsage(
    promise: com.facebook.react.bridge.Promise
  ) {
    val stat = android.os.StatFs(
      android.os.Environment.getDataDirectory().path
    )
    val map = WritableNativeMap().apply {
      putDouble("used", (stat.totalBytes - stat.availableBytes).toDouble())
      putDouble("total", stat.totalBytes.toDouble())
    }
    promise.resolve(map)
  }

  override fun getName(): String = "DeviceInfo"
}

重要なポイントは、getDeviceModel()getOSVersion()getBatteryLevel()が同期的であることです。JavaScriptスレッドがネイティブコードに直接呼び出しを行い、同じティックで戻り値を受け取ります。Promiseもコールバックもブリッジのラウンドトリップもありません。これはJSIによってのみ実現可能です。

ブリッジレスモード:何が削除され、なぜ重要なのか

ブリッジレスモードはReact Native 0.73で導入され、0.74でデフォルトになりました。FabricやTurboModulesが採用された後でも、旧ブリッジはグローバルイベントエミッタ、タイマー、エラーハンドリングを処理するために起動時に初期化されていました。ブリッジレスモードは、これらの残りのシステムをJSIベースの実装に移行します。

実際の影響は以下の通りです。

  • 高速な起動:ブリッジ初期化のオーバーヘッドがありません。ランタイムは遅延ロードにより、アプリが実際に使用するものだけをブートストラップします。
  • メモリの削減:起動時にブリッジのデータ構造が割り当てられません。
  • クリーンなエラーハンドリング:エラーバウンダリとグローバルエラーハンドラが、ブリッジのフォールバックなしに新アーキテクチャを通じて動作します。

React Native 0.82で旧ブリッジが恒久的に無効化されました。2026年4月にリリースされたReact Native 0.85では、ブリッジ関連のすべてのコードがコードベースから削除されています。フォールバックパスは存在しません。

本番環境の移行:実際のパフォーマンスベンチマーク

旧アーキテクチャから新アーキテクチャへの本番環境の移行では、主要メトリクスにわたって一貫した改善が見られます。

| メトリクス | 旧アーキテクチャ | 新アーキテクチャ | 改善 | |-----------|-----------------|------------------|------| | コールドスタート(TTI) | 1.4秒 | 0.8秒 | 43%高速化 | | 画面遷移 | 180ms | 110ms | 39%高速化 | | メモリベースライン | 89MB | 66MB | 26%削減 | | JS→ネイティブ呼び出し | 約5ms(非同期) | 約0.1ms(同期) | 40倍高速化 | | GC最大ポーズ | 45ms | 12ms | 73%短縮 | | FlatListスクロール(1000アイテム) | 時折ジャンク発生 | スムーズな60fps | フレームドロップなし |

ユーザー体験の品質に最も大きな影響を与える改善は、GCポーズの短縮です。Hadesはコレクションポーズを1フレーム予算(60fpsで16.6ms)未満に抑え、複雑なReact Nativeアプリにおける最も一般的な目に見えるジャンクの原因を排除します。

2026年のエコシステム互換性

エコシステムは新アーキテクチャに完全に収束しています。Expo SDK 55以降は新アーキテクチャ上でのみ動作し、無効にするオプションはありません。主要ライブラリの互換性は以下の通りです。

  • React Navigation 7.2以降:ネイティブスタック画面を含む完全なFabricサポート
  • Reanimated 3.5以降:React Native 0.85との共有アニメーションバックエンド
  • Gesture Handler 2.16以降:JSIベースの直接ジェスチャ認識
  • Vision Camera 4.0以降:JSIによるフレーム処理
  • Detox:新アーキテクチャ対応のE2Eテスト

Expoを使用するチームの場合、npx create-expo-appは新アーキテクチャがデフォルトで有効になったプロジェクトを生成します。設定は不要です。

React Native 0.75以前のアプリは移行が必要です。旧ブリッジは0.82以降で恒久的に削除されています。ブリッジに依存するサードパーティライブラリ(TurboModule specなしにNativeModulesを直接使用するもの)は更新が必要です。

技術面接の質問:React Native新アーキテクチャ

これらの質問は、2026年のシニアReact Nativeエンジニアの面接で頻出します。各回答は、スタッフ/シニアレベルで期待される深さをカバーしています。

Q1:旧ブリッジとJSIの違いを説明してください。なぜJSIは同期的なネイティブ呼び出しを可能にするのですか?

ブリッジは、JS→ネイティブのすべてのメッセージをJSONにシリアライズし、非同期キューに入れ、ネイティブ側でデシリアライズしていました。JSI(JavaScript Interface)は、C++ホストオブジェクトをJavaScript VMに直接公開します。JSIを通じて登録されたネイティブ関数は、シリアライズやキューイングなしにネイティブコードをインラインで実行する通常のJavaScript関数として表示されます。JSIは中間メッセージキューなしに同じスレッドコンテキストで動作するため、同期呼び出しが可能です。

Q2:FabricレンダラーはPaperでは解決できなかったどのような問題を解決しますか?

Paperはブリッジを介して非同期にレンダリングを行っていたため、Reactの並行機能をサポートすることが不可能でした。Paperは進行中のレンダーツリーを中断できなかったため、startTransitionの呼び出しは効果がありませんでした。Fabricは共有C++コードでレンダリングを実装し、React 19のリコンサイラーと直接統合し、並行レンダリング、Suspense、Transitionsをサポートします。Yogaによるレイアウト計算も同じメモリ空間で同期的に行われ、クロスブリッジレイアウトのレイテンシが排除されます。

Q3:新アーキテクチャにHermesが必要な理由は何ですか?他のエンジンを使用することは可能ですか?

新アーキテクチャはJSIに依存しており、JSIはJavaScriptエンジンがC++ホストオブジェクト登録をサポートする必要があります。HermesはJSI統合を前提としてゼロから設計されました。JavaScriptCoreも理論上JSIをサポートできますが、公式の実装とテストはHermes向けに構築されています。Hermes V1は、バイトコードのプリコンパイル(実行時のパースを排除)、Hades並行GC(12ms未満のポーズ)、WebAssemblyサポートを追加で提供しますが、これらはReact NativeのJSC統合では利用できません。

Q4:TurboModulesは開発者の観点から旧NativeModules APIとどのように異なりますか?

TurboModulesには、ビルド時に型安全なネイティブバインディングを生成するCodegen spec(TurboModuleを拡張するTypeScriptインターフェース)が必要です。旧NativeModulesは型チェックなしのランタイムリフレクションを使用していました。TurboModulesは同期的な戻り値(Promiseだけでなく)、遅延初期化(モジュールは最初のアクセス時にのみロード)、JSONシリアライズなしの直接JSI呼び出しをサポートします。開発者はTypeScriptのspecを書き、Codegenを実行し、生成されたネイティブインターフェースを実装します。

Q5:ブリッジレスモードについて説明し、FabricとTurboModulesだけの場合と比較して何が削除されるか述べてください。

FabricとTurboModulesを採用した後でも、旧ブリッジはグローバルイベントエミッタ、タイマー、エラーハンドリング、その他のランタイムインフラストラクチャを処理するために起動時に初期化されていました。ブリッジレスモードは、これらの残りのブリッジ依存システムをJSIベースの実装に置き換えます。ブリッジ初期化のオーバーヘッドを排除し、ベースラインメモリ使用量を削減し、ランタイム全体がJSIを通じて動作することを保証します。React Native 0.85以降、ブリッジレスモードが唯一の動作モードです。

これらの質問をコード例とともに練習することで、概念的な理解と実践的な想起力の両方が強化されます。

React Nativeの面接対策はできていますか?

インタラクティブなシミュレーター、flashcards、技術テストで練習しましょう。

まとめ

  • Hermes V1は、React Native 0.84以降でコールドスタートの29%高速化、メモリの38%削減、12ms未満のGCポーズを標準で実現します
  • FabricはPaperでは決してサポートできなかったReact 19の並行機能(Transitions、Suspense)を可能にします
  • TurboModulesはJSONシリアライズを排除し、直接JSI呼び出しによりJS→ネイティブ呼び出しを40倍高速化します
  • ブリッジレスモードは最後のブリッジ依存関係を除去し、React Native 0.85にはブリッジコードが一切残っていません
  • エコシステムは完全に対応済みです。Expo SDK 55以降、React Navigation 7.2以降、Reanimated 3.5以降、すべての主要ライブラリが新アーキテクチャのみをサポートしています
  • 面接対策では、JSIのメカニズム、FabricとPaperのトレードオフ、TurboModule Codegenのワークフロー、ブリッジレスモードのランタイム変更に焦点を当てるべきです

タグ

#react-native
#hermes
#new-architecture
#turbomodules
#fabric
#bridgeless

共有

関連記事