ブログ記事

React Native新アーキテクチャ完全ガイド2025 - Fabric & TurboModulesでパフォーマンスを最大化

React Nativeの新アーキテクチャ(Fabric、TurboModules、JSI)の詳細解説。移行方法、パフォーマンス最適化、実装例を含む包括的なガイドで、高速なモバイルアプリ開発を実現します。

Web開発
React Native Fabric TurboModules モバイル開発 パフォーマンス
React Native新アーキテクチャ完全ガイド2025 - Fabric & TurboModulesでパフォーマンスを最大化のヒーロー画像

React Native の新アーキテクチャは、2025 年の今、モバイルアプリ開発に革命をもたらしています。Fabric、TurboModules、JSI という 3 つの核心技術により、ネイティブアプリに匹敵するパフォーマンスと開発効率を実現。本記事では、新アーキテクチャの全貌を詳細に解説し、実践的な移行方法とパフォーマンス最適化のテクニックを紹介します。

この記事で学べること

  • React Native 新アーキテクチャの 3 つの核心技術(Fabric、TurboModules、JSI)
  • 従来のアーキテクチャとの違いとメリット
  • 段階的な移行戦略と実装方法
  • パフォーマンス最適化の具体的なテクニック
  • 実践的なコード例とベストプラクティス

React Native新アーキテクチャの概要

React Native の新アーキテクチャは、2018 年から開発が始まり、2025 年現在では多くのプロダクションアプリで採用されています。従来のブリッジベースのアーキテクチャから、より直接的で高速な通信メカニズムへの移行により、パフォーマンスとユーザー体験が大幅に向上しました。

新アーキテクチャの構成要素

チャートを読み込み中...

新アーキテクチャの3つの柱

新アーキテクチャの核心技術
技術 役割 主な改善点
JSI(JavaScript Interface) JS-ネイティブ間の直接通信 JSONシリアライゼーション不要、同期的な関数呼び出し
Fabric 新しいレンダリングシステム 同期的レイアウト、優先度制御、スムーズなアニメーション
TurboModules 遅延読み込み対応のネイティブモジュール 起動時間の短縮、型安全性、コードの自動生成

従来のアーキテクチャとの比較

新アーキテクチャがもたらす変化を理解するために、従来のアーキテクチャとの違いを詳しく見ていきましょう。

アーキテクチャの進化

React Native初期リリース

ブリッジベースのアーキテクチャでクロスプラットフォーム開発を実現

新アーキテクチャの開発開始

パフォーマンスとユーザー体験の根本的改善を目指す

Facebook社内での採用

大規模アプリでの実証実験と最適化

React Native 0.76でデフォルト化

新アーキテクチャが標準となる

広範な採用と成熟

多くのプロダクションアプリで活用され、エコシステムも充実

通信メカニズムの違い

// 非同期でJSONを介した通信 // JavaScript側 NativeModules.MyModule.doSomething(data, (result) => { // 非同期コールバックで結果を受け取る console.log(result); }); // Native側(iOS) RCT_EXPORT_METHOD(doSomething:(NSDictionary *)data callback:(RCTResponseSenderBlock)callback) { // JSONをパースして処理 NSString *result = [self processData:data]; // JSONにシリアライズして返す callback(@[result]); }
// 同期的で直接的な通信 // JavaScript側 const result = global.MyModule.doSomething(data); // 即座に結果を取得 console.log(result); // Native側(C++) jsi::Value doSomething(jsi::Runtime& runtime, const jsi::Value& data) { // 直接データを処理(シリアライゼーション不要) auto result = processData(data); // 直接値を返す return jsi::String::createFromUtf8(runtime, result); }
従来のブリッジアーキテクチャ
// 非同期でJSONを介した通信 // JavaScript側 NativeModules.MyModule.doSomething(data, (result) => { // 非同期コールバックで結果を受け取る console.log(result); }); // Native側(iOS) RCT_EXPORT_METHOD(doSomething:(NSDictionary *)data callback:(RCTResponseSenderBlock)callback) { // JSONをパースして処理 NSString *result = [self processData:data]; // JSONにシリアライズして返す callback(@[result]); }
新アーキテクチャ(JSI)
// 同期的で直接的な通信 // JavaScript側 const result = global.MyModule.doSomething(data); // 即座に結果を取得 console.log(result); // Native側(C++) jsi::Value doSomething(jsi::Runtime& runtime, const jsi::Value& data) { // 直接データを処理(シリアライゼーション不要) auto result = processData(data); // 直接値を返す return jsi::String::createFromUtf8(runtime, result); }

JSI(javascript Interface)の詳細

JSI は新アーキテクチャの基盤となる技術で、javascript とネイティブコード間の直接的な通信を可能にします。

JSIの主要な特徴

JSIがもたらす革新

  • 同期的な関数呼び出し: ネイティブ関数を同期的に呼び出し可能
  • 共有メモリ: オブジェクトの直接参照でコピーコスト削減
  • HostObject: ネイティブオブジェクトを javascript から直接操作
  • 低レイテンシ: json シリアライゼーションのオーバーヘッドを排除

JSI実装例

// JSIを使用したネイティブモジュールの実装
class NativeCalculator : public jsi::HostObject {
public:
  jsi::Value get(jsi::Runtime& runtime, const jsi::PropNameID& name) override {
    auto propName = name.utf8(runtime);
    
    if (propName == "add") {
      return jsi::Function::createFromHostFunction(
        runtime,
        jsi::PropNameID::forAscii(runtime, "add"),
        2, // 引数の数
        [](jsi::Runtime& runtime, const jsi::Value& thisValue,
           const jsi::Value* arguments, size_t count) -> jsi::Value {
          double a = arguments[0].asNumber();
          double b = arguments[1].asNumber();
          return jsi::Value(a + b);
        }
      );
    }
    
    return jsi::Value::undefined();
  }
};

// JavaScriptへの公開
void installCalculator(jsi::Runtime& runtime) {
  auto calculator = std::make_shared<NativeCalculator>();
  runtime.global().setProperty(
    runtime,
    "NativeCalculator",
    jsi::Object::createFromHostObject(runtime, calculator)
  );
}

Fabric: 新しいレンダリングシステム

Fabric は、react Native の新しいレンダリングシステムで、より効率的でレスポンシブな ui を実現します。

Fabricの核心機能

同期的レイアウト 100 %
完了
マルチスレッド処理 95 %
優先度制御 90 %
メモリ効率 85 %

レンダリングパイプラインの比較

Fabricのレンダリングフロー

チャートを読み込み中...

Fabric実装例

// Fabricコンポーネントの定義
import { requireNativeComponent, ViewProps } from 'react-native';
import type { HostComponent } from 'react-native';

// 型安全なFabricコンポーネント
interface CustomViewProps extends ViewProps {
  color?: string;
  onCustomEvent?: (event: { nativeEvent: { value: string } }) => void;
}

// Fabricコンポーネントの取得
const CustomViewNative: HostComponent<CustomViewProps> = 
  requireNativeComponent('CustomView');

// ラッパーコンポーネント
export function CustomView(props: CustomViewProps) {
  return <CustomViewNative {...props} />;
}
// 同期的なレイアウト測定
import { useLayoutEffect, useRef } from 'react';
import { View, findNodeHandle } from 'react-native';

function MeasuredComponent() {
  const viewRef = useRef<View>(null);
  
  useLayoutEffect(() => {
    // Fabricでは同期的に測定可能
    const handle = findNodeHandle(viewRef.current);
    if (handle) {
      viewRef.current?.measure((x, y, width, height, pageX, pageY) => {
        console.log('同期的に測定:', { width, height });
        // レイアウトに基づいた即座の更新が可能
      });
    }
  }, []);
  
  return <View ref={viewRef} />;
}
// Fabricで最適化されたアニメーション
import { Animated, useAnimatedValue } from 'react-native';
import { useEffect } from 'react';

function OptimizedAnimation() {
  const animValue = useAnimatedValue(0);
  
  useEffect(() => {
    // Fabricでは優先度制御により滑らかなアニメーション
    Animated.timing(animValue, {
      toValue: 1,
      duration: 300,
      useNativeDriver: true, // Fabricで最適化
    }).start();
  }, []);
  
  return (
    <Animated.View
      style={{
        opacity: animValue,
        transform: [{
          scale: animValue.interpolate({
            inputRange: [0, 1],
            outputRange: [0.8, 1],
          }),
        }],
      }}
    >
      {/* コンテンツ */}
    </Animated.View>
  );
}

TurboModules: 高速なネイティブモジュール

TurboModules は、ネイティブモジュールの新しい実装方式で、遅延読み込みと型安全性を提供します。

TurboModulesの利点

TurboModulesの性能改善データ
特徴 説明 効果
遅延初期化 使用時にのみモジュールを読み込み 起動時間を最大50%短縮
型安全性 CodeGenによる自動型生成 実行時エラーの大幅削減
同期呼び出し JSI経由の直接呼び出し レイテンシを90%削減
プラットフォーム共通化 C++での実装共有 コード重複を70%削減
自動バインディング 手動ブリッジ実装不要 開発時間を60%短縮

TurboModule実装例

// TurboModuleの定義(TypeScript)
// NativeCalculator.ts
import type { TurboModule } from 'react-native';
import { TurboModuleRegistry } from 'react-native';

export interface Spec extends TurboModule {
  add(a: number, b: number): number;
  multiply(a: number, b: number): number;
  divide(a: number, b: number): Promise<number>;
}

export default TurboModuleRegistry.getEnforcing<Spec>('Calculator');
// ネイティブ実装(C++)
// NativeCalculator.cpp
#include "NativeCalculator.h"

namespace facebook::react {

NativeCalculator::NativeCalculator(std::shared_ptr<CallInvoker> jsInvoker)
    : NativeCalculatorCxxSpec(std::move(jsInvoker)) {}

double NativeCalculator::add(jsi::Runtime& rt, double a, double b) {
  return a + b;
}

double NativeCalculator::multiply(jsi::Runtime& rt, double a, double b) {
  return a * b;
}

jsi::Value NativeCalculator::divide(
    jsi::Runtime& rt,
    double a,
    double b) {
  // Promise を返す非同期操作の例
  return createPromiseAsJSIValue(
      rt,
      [a, b](jsi::Runtime& rt, std::shared_ptr<Promise> promise) {
        if (b == 0) {
          promise->reject("Division by zero");
        } else {
          promise->resolve(jsi::Value(a / b));
        }
      });
}

} // namespace facebook::react

新アーキテクチャへの移行戦略

既存の react Native アプリを新アーキテクチャに移行する際の戦略を解説します。

段階的移行アプローチ

準備と評価

依存関係の確認、互換性チェック、影響範囲の特定

開発環境の更新

React Native 0.76以上へアップグレード、ツールチェーンの更新

部分的な有効化

新アーキテクチャを部分的に有効化してテスト

ライブラリの移行

サードパーティライブラリの互換性確認と更新

本番展開

段階的なロールアウトとモニタリング

移行チェックリスト

移行前の確認事項

  • React Native 0.76 以上へのアップグレード
  • 全てのネイティブ依存関係の互換性確認
  • カスタムネイティブモジュールの更新計画
  • Ci/cd パイプラインの調整
  • パフォーマンステストの準備

プラットフォーム別の有効化

# ios/Podfile # 新アーキテクチャを有効化 use_react_native!( :path => config[:reactNativePath], # 以下の行を追加 :fabric_enabled => true, :turbo_modules_enabled => true, # オプション設定 :hermes_enabled => true, :flipper_configuration => flipper_config, ) # ビルド設定 post_install do |installer| react_native_post_install( installer, config[:reactNativePath], # ビルド設定のカスタマイズ :mac_catalyst_enabled => false ) end
# android/gradle.properties # 新アーキテクチャの有効化 newArchEnabled=true # TurboModulesの有効化 turboModulesEnabled=true # Hermesの有効化(推奨) hermesEnabled=true # オプション: ビルド最適化 android.enableJetifier=true android.useAndroidX=true # メモリ設定 org.gradle.jvmargs=-Xmx4g -XX:MaxPermSize=2048m org.gradle.parallel=true
iOS(Podfile)
# ios/Podfile # 新アーキテクチャを有効化 use_react_native!( :path => config[:reactNativePath], # 以下の行を追加 :fabric_enabled => true, :turbo_modules_enabled => true, # オプション設定 :hermes_enabled => true, :flipper_configuration => flipper_config, ) # ビルド設定 post_install do |installer| react_native_post_install( installer, config[:reactNativePath], # ビルド設定のカスタマイズ :mac_catalyst_enabled => false ) end
Android(gradle.properties)
# android/gradle.properties # 新アーキテクチャの有効化 newArchEnabled=true # TurboModulesの有効化 turboModulesEnabled=true # Hermesの有効化(推奨) hermesEnabled=true # オプション: ビルド最適化 android.enableJetifier=true android.useAndroidX=true # メモリ設定 org.gradle.jvmargs=-Xmx4g -XX:MaxPermSize=2048m org.gradle.parallel=true

パフォーマンス最適化テクニック

新アーキテクチャを最大限に活用するためのパフォーマンス最適化テクニックを紹介します。

1. リスト最適化

// 最適化されたFlatListの実装
import { FlatList, Text, View } from 'react-native';
import { memo, useCallback } from 'react';

// メモ化されたアイテムコンポーネント
const ListItem = memo(({ item, onPress }) => {
  return (
    <TouchableOpacity onPress={() => onPress(item)}>
      <View style={styles.item}>
        <Text>{item.title}</Text>
      </View>
    </TouchableOpacity>
  );
});

function OptimizedList({ data }) {
  // レンダリング最適化
  const renderItem = useCallback(({ item }) => (
    <ListItem item={item} onPress={handlePress} />
  ), []);
  
  const keyExtractor = useCallback((item) => item.id, []);
  
  const getItemLayout = useCallback((data, index) => ({
    length: ITEM_HEIGHT,
    offset: ITEM_HEIGHT * index,
    index,
  }), []);
  
  return (
    <FlatList
      data={data}
      renderItem={renderItem}
      keyExtractor={keyExtractor}
      getItemLayout={getItemLayout}
      // Fabric最適化オプション
      removeClippedSubviews={true}
      maxToRenderPerBatch={10}
      updateCellsBatchingPeriod={50}
      windowSize={10}
      initialNumToRender={10}
    />
  );
}

2. 画像最適化

画像最適化のベストプラクティス
最適化手法 実装方法 効果
遅延読み込み FastImageやExpo Imageの使用 初期読み込み時間を60%短縮
キャッシュ戦略 メモリとディスクキャッシュの併用 再読み込み時間を90%短縮
プログレッシブ読み込み 低解像度から高解像度へ段階的表示 体感速度を向上
フォーマット最適化 WebPやAVIFの使用 ファイルサイズを40%削減
サイズ最適化 デバイスに応じた画像サイズ メモリ使用量を50%削減

3. バンドルサイズ最適化

// Metro設定でのコード分割
// metro.config.js
module.exports = {
  transformer: {
    minifierConfig: {
      keep_fnames: true,
      mangle: {
        keep_fnames: true,
      },
    },
    getTransformOptions: async () => ({
      transform: {
        experimentalImportSupport: true,
        inlineRequires: true, // 遅延読み込みを有効化
      },
    }),
  },
  resolver: {
    // 不要なファイルを除外
    blacklistRE: /(__tests__|\.test\.|\.spec\.)\.js$/,
  },
};

実践的なユースケース

新アーキテクチャを活用した実践的な実装例を紹介します。

ユースケース1: リアルタイムチャットアプリ

新アーキテクチャの導入により、メッセージの表示遅延が 300ms から 50ms 以下に改善され、ユーザー体験が劇的に向上しました。特に Fabric による同期的レンダリングの恩恵が大きいです。

開発チーム シニアエンジニア
// リアルタイムチャットの最適化実装
import { useEffect, useRef, useState } from 'react';
import { FlatList, KeyboardAvoidingView } from 'react-native';

function ChatScreen() {
  const [messages, setMessages] = useState([]);
  const flatListRef = useRef(null);
  
  // WebSocketとの統合
  useEffect(() => {
    const ws = new WebSocket('wss://chat-server.com');
    
    ws.onmessage = (event) => {
      const newMessage = JSON.parse(event.data);
      
      // Fabricによる高速レンダリング
      setMessages(prev => [...prev, newMessage]);
      
      // 同期的なスクロール
      requestAnimationFrame(() => {
        flatListRef.current?.scrollToEnd({ animated: true });
      });
    };
    
    return () => ws.close();
  }, []);
  
  return (
    <KeyboardAvoidingView style={{ flex: 1 }} behavior="padding">
      <FlatList
        ref={flatListRef}
        data={messages}
        renderItem={({ item }) => <MessageItem message={item} />}
        // 最適化設定
        maintainVisibleContentPosition={{
          minIndexForVisible: 0,
        }}
        inverted
      />
    </KeyboardAvoidingView>
  );
}

ユースケース2: 高性能な地図アプリ

// TurboModuleを活用した地図実装
import MapModule from './NativeMapModule';
import { useEffect, useState } from 'react';

function HighPerformanceMap() {
  const [markers, setMarkers] = useState([]);
  
  useEffect(() => {
    // TurboModuleの同期的な呼び出し
    const bounds = MapModule.getVisibleBounds();
    const nearbyPOIs = MapModule.queryPOIsInBounds(bounds);
    
    // 高速なマーカー更新
    setMarkers(nearbyPOIs);
  }, []);
  
  const handleRegionChange = (region) => {
    // リアルタイムでの領域クエリ
    requestIdleCallback(() => {
      const pois = MapModule.queryPOIsInRegion(region);
      setMarkers(pois);
    });
  };
  
  return (
    <MapView
      onRegionChangeComplete={handleRegionChange}
      markers={markers}
    />
  );
}

トラブルシューティング

新アーキテクチャ導入時によく遭遇する問題と解決策をまとめました。

よくある問題と解決策
問題 原因 解決策
ビルドエラー 古いネイティブ依存関係 pod install --repo-updateとgradle cleanを実行
クラッシュ 互換性のないライブラリ ライブラリを最新版に更新または代替を検討
パフォーマンス低下 最適化されていないコード React DevToolsでプロファイリング実施
レイアウトの崩れ Fabricの同期レンダリング useLayoutEffectで同期的に処理
メモリリーク ネイティブ側の参照保持 適切なクリーンアップ処理を実装

ベストプラクティスとまとめ

新アーキテクチャを最大限に活用するためのベストプラクティスを紹介します。

開発のベストプラクティス

推奨される開発手法

  1. 段階的な移行: 全てを一度に移行せず、モジュールごとに進める
  2. 型安全性の活用: CodeGen と typescript で型の一貫性を保つ
  3. パフォーマンス計測: 移行前後でのメトリクス比較を必ず実施
  4. ネイティブ知識の習得: C++や JSI の基礎を理解する
  5. コミュニティの活用: 問題解決には公式 Discussions を活用

パフォーマンス指標

起動時間の改善 85 %
レンダリング速度 92 %
メモリ使用量の削減 78 %
アニメーションの滑らかさ 95 %

まとめ

React Native の新アーキテクチャは、モバイルアプリ開発に革命的な変化をもたらしています。本記事で解説した内容をまとめます:

本記事のポイント

  • Fabric、TurboModules、JSI の 3 つの技術が新アーキテクチャの核心
  • 同期的な通信とレンダリングにより、大幅なパフォーマンス向上を実現
  • 段階的な移行戦略により、リスクを最小限に抑えた導入が可能
  • 適切な最適化により、ネイティブアプリに匹敵する体験を提供
  • 2025 年現在、多くのプロダクションアプリで実証済みの技術

新アーキテクチャは、react Native の可能性を大きく広げ、真にネイティブ品質のアプリケーション開発を可能にします。本記事を参考に、ぜひ新アーキテクチャへの移行を検討してください。

この記事は役に立ちましたか?

Daily Hackでは、開発者の皆様に役立つ情報を毎日発信しています。