📱

React Nativeとはなにか。採用のメリットとデメリット

2024/12/01に公開

この記事はReact Native 全部俺 Advent Calendar 1日目の記事です。

このアドベントカレンダーについて

このアドベントカレンダーは @itome が全て書いています。

基本的にReact NativeおよびExpoの公式ドキュメントとソースコードを参照しながら書いていきます。誤植や編集依頼はXにお願いします。

React Nativeとは?採用のメリットとデメリット

昨今のモバイルアプリ開発において、AndroidとiOSの両方に対応することは必須となっています。しかし、各プラットフォーム向けに別々の開発チームを持つことは、特にスタートアップなどのリソースが限られている組織にとって大きな負担となります。

React Nativeは、FacebookによってオープンソースとしてAndroid/iOSアプリの開発を可能にするライブラリです。その最大の特徴は「Learn once, write anywhere」というスローガンに端的に表されています。これは、React(およびJavaScript/TypeScript)の知識があれば、両プラットフォームのアプリを開発できることを意味します。

Expoによる開発環境

React Nativeアプリの開発には、主にExpoを利用します。ExpoはReact Native開発のためのフレームワークで、以下のような機能を提供します。

  • プロジェクトの作成から実機での動作確認までの開発環境のセットアップ
  • プッシュ通知やアプリ内課金などの一般的なネイティブ機能へのアクセス
  • Over-The-Air (OTA) アップデートによるアプリの即時更新

プロジェクトの作成は以下のコマンドで行えます:

npx create-expo-app my-app
cd my-app
npm start

Expoに関する詳しい内容は2日目の記事で紹介します。

仕組み

React NativeはReactのコンポーネントをネイティブのプラットフォームコンポーネントにブリッジします。例えば以下のようなReactコードは

import { View, Text } from 'react-native';

function MyComponent() {
  return (
    <View style={styles.container}>
      <Text style={styles.text}>Hello, React Native!</Text>
    </View>
  );
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    justifyContent: 'center',
    alignItems: 'center'
  },
  text: {
    fontSize: 24,
    fontWeight: 'bold'
  }
});

iOSではUIViewUILabelに、Androidではandroid.view.Viewandroid.widget.TextViewに変換されてネイティブのUIとして描画されます。

スタイリングにはFlexboxベースのレイアウトエンジンが採用されており、CSSライクな記法でUIを構築できます。特にExpo環境では、@expo/vector-iconsやLinear Gradientなど、一般的なUIコンポーネントがすぐに利用可能です。

採用企業と実績

React Nativeは多くの大手企業で採用されており、その実績は信頼性の証となっています。

  • Discord: チャットアプリの代表格であるDiscordは、2015年からReact Nativeを採用しているようです。筆者も日常的に使っていますが、今回調べてReact Native製だと知りびっくりしました。

  • Instagram: React Nativeの開発元であるMetaが運営するInstagramでは、Meta Quest向けのアプリをReact Nativeで作成しています。

  • Shopify: eコマースプラットフォーム大手のShopifyは、商品管理やオーダー管理など、複雑なビジネスロジックを含むアプリをReact Nativeで開発しています。

メリット

効率的なクロスプラットフォーム開発

React Nativeの最大の利点は、単一のコードベースで両プラットフォームのアプリを開発できることです。公式ドキュメントによると、平均して約90%のコードを共有できるとされています。

import { Platform } from 'react-native';

// プラットフォーム固有のスタイルが必要な場合も簡単に分岐可能
const styles = StyleSheet.create({
  shadow: Platform.select({
    ios: {
      shadowColor: 'black',
      shadowOffset: { width: 0, height: 2 },
      shadowOpacity: 0.25,
    },
    android: {
      elevation: 4,
    },
  }),
});

アプリ開発とデプロイがはやい

React Nativeでは、iOSとAndroidのアプリを同時に作ることができるため効率的なのはもちろん、HotReloadingによる効率的なUI開発や、ChromeのDevToolを使ったデバッグなど、早くアプリを作るために必要な要素が揃っています。

さらにExpo環境では、以下のような開発効率化の機能が提供されます

  • Development Build: 実機でのデバッグが簡単に行える
  • EAS Build: クラウド上でアプリのビルドが可能
  • EAS Update: アプリストアを介さずにJavaScriptの更新が可能

豊富なライブラリ群

React NativeはTypescript(or Javascript)とReactを使って開発をするため、Webのコミュニティによって開発された多くのライブラリをそのまま使うことができます。また、React Native用に書かれたライブラリも多く存在し、よほど特殊な機能や最新のAPIを利用しない限り、そのようなライブラリを使いながら開発を進めることが可能です。

デメリット

Expo Goの制限事項

Expo Go環境では一部のネイティブ機能にアクセスできない制限があります

  • Bluetooth通信
  • バックグラウンドでの位置情報取得
  • 特定のサードパーティSDK

これらの機能が必要な場合は、Expo Goアプリでのデバッグができなくなるため、Development Buildを使用しなければなりません。
しかし、2020年ごろに私がReact Nativeを使っていたときはこのようなケースではそもそもExpoの利用を諦めなければいけなかったため、大きく進化した部分だと言えます。

パフォーマンスについて

従来のReact Nativeでは、JavaScriptとネイティブコード間のブリッジ通信がボトルネックとなることがありました。しかし、2023年にリリースされたNew Architectureでは、以下のような改善が行われています

  • Fabric Renderer: UIコンポーネントの同期的なレンダリングを実現し、従来のブリッジによる非同期通信を解消
  • Turbo Modules: ネイティブモジュールの呼び出しをTypeScript/JavaScriptから直接行えるように
  • Codegen: 型安全なネイティブモジュールの自動生成

特に画面の描画に関するパフォーマンスは大幅に改善され、以下のような機能でもネイティブに近いパフォーマンスを実現できます

  • 複雑なアニメーション
  • スクロール時のリスト描画
  • インタラクティブな画面遷移

ただし、以下のような場合は依然として注意が必要です

  • 大量のデータを扱う処理
  • 複雑な画像処理
  • バックグラウンドでの長時間の処理

これらについては、必要に応じてネイティブモジュールの利用を検討するのがよいでしょう。

Discussion