決闘:ReactNativeとCordova
公開: 2022-03-11スマートフォンやモバイルアプリケーションの人気が高まった結果、Web開発者はJavaScriptを使用してモバイルアプリケーションを作成する方法を模索してきました。 この人気により、モバイルデバイスでネイティブのようなアプリケーションを実行できる多くのJavaScriptフレームワークが開発されました。 現在、CordovaとReactNativeが最も人気のある選択肢です。 Cordovaは、iOS、Android、およびWindowsPhoneモバイルプラットフォームをサポートしています。 一方、React Nativeでは、Android、iOS、およびUWPが開発者のターゲットです。 (UWPはユニバーサルWindowsプラットフォームの略で、同じアプリケーションをWindows Phone 10 Mobile、XBox One、およびWindows 10で実行できるようにするMicrosoftのプラットフォームです。)
表面からは、ReactNativeとCordovaが同じスペースを占めているように見えます。 ただし、すべてのテクノロジーと同様に、一方が輝いていて、もう一方が不十分な側面があります。 したがって、各テクノロジーの全体像を把握し、それらの利点と落とし穴を学ぶために、それぞれの詳細を掘り下げて、さまざまな分野で比較します。
哲学の違い
React Nativeのタグラインである「一度学習してどこでも書く」は、通常のクロスプラットフォームのマントラ「一度書くだけでどこでも実行する」とは異なることを覚えておくことが重要です。 これは2つのことにつながります。1つは、既存のReactコードベースをWebプロジェクトから取得して、数回クリックするだけでモバイルアプリケーションに変換することはできません。 ただし、ReactとReact Nativeは多くの重要な概念を共有しており、その1つの例はコンポーネントシステムであるため、ReactNativeはすぐに馴染みがあると感じます。 ReactはReactNativeと多くの類似点を共有していますが、スタイルシートの処理方法から使用できるコンポーネントの種類まで、いくつかの主要な違いがあります。
次に、異なるプラットフォームをターゲットにすると、ReactNativeコードを共有できない場合があります。 これは、ユーザーインターフェース要素を特定のプラットフォームに対してネイティブに動作させ、ユーザーにアプリのエクスペリエンスとネイティブ感を向上させたい場合に発生します。 明らかな例は、Androidアプリのドロワーサイドメニューです。これは、iOSアプリでは非常にまれです。
コルドバはこの哲学を共有していません。 純粋なWebアプリケーションの開発を開始し、後でそれをCordovaアプリケーションとしてバンドルし、ターゲットとするすべての(モバイル)プラットフォームで可能な限り多くのコードを再利用することは珍しくありません。
開発の自由
モバイルデバイスでは、CordovaはWebViewと呼ばれる統合モバイルWebブラウザー内で単一ページのアプリケーションを実行し、それをネイティブアプリケーションとしてラップします。 外部からはネイティブアプリケーションのように見えますが、Webコードはモバイルブラウザエンジン内で実行されています。 私たちにとって、それは私たちが特定のライブラリやフレームワークに縛られていないことを意味します。 バニラJavaScript、jQuery、Angularなどを使用している場合、これらのオプションのいずれかをCordovaを使用してモバイルアプリケーションにバンドルできます。 コルドバは私たちのテクノロジースタックに課しません。 index.html
ファイルがある限り、問題ありません。 簡単な例の1つは、次のコードスニペットです。
<html> <head> <title>My Cordova App</title> </head> <body> <div>Tap me</div> <script> // Select our element var element = document.getElementById('tapme'); // Send an alert once it was tapped/clicked element.addEventListener('click', function() { alert('Hello there!'); }); </script> </body> </html>
この例は、NPMやBowerなどのパッケージマネージャー、Babel、CoffeeScript、TypeScriptなどのトランスパイラー、WebpackやRollupなどのバンドラーなど、必要なものをほぼすべて使用できることを意味します。 結果が、必要なすべてのJavaScriptとスタイルシートをロードするindex.html
ファイルである限り、問題ではありません。
React Nativeは、その名前が示すように、Reactに基づいて構築されています。 React NativeのReact部分は、そのコア機能の1つであることを理解することが重要です。 JSX、そのコンポーネント化、データフローなど、Reactの宣言型の性質が好きでない場合は、ReactNativeに満足できない可能性があります。 React NativeはすぐにReact開発者に馴染みがあるように感じますが、一見すると、覚えておくべきいくつかの違いがあります。 React Nativeには、HTMLやCSSはありません。 代わりに、このテクノロジーはJavaScript側に焦点を合わせています。 CSSの代わりに、スタイルはインラインで記述されており、Flexboxがデフォルトのスタイリングモデルです。
最も必要最低限のReactNativeアプリケーションは、次の例のようになります。
// Import the React module for JSX conversion import { React } from 'react'; // Import React Native's components import { View, Text, AppRegistry, TouchableOpacity, } from 'react-native'; // Create an App component const App = () => { // Define our press handler const onPress = () => alert('Hello there!'); // Compose the components we are going to render return ( <View> <TouchableOpacity onPress={onPress} /> <Text>Tap me!</Text> </TouchableOpacity> </View> ); }; // Registers the `App` component as our main entry point AppRegistry.registerComponent('App', () => App);
ReactNativeには独自のパッケージャーがあります。 すべてのJavaScriptファイルを1つの巨大なファイルにバンドルし、AppleのJavaScriptエンジンであるJavaScriptCoreによって消費および実行されます。 JavaScriptCoreはiOSとAndroidで使用されており、ChakraCoreはReactNativeUWPアプリケーションを強化しています。 デフォルトでは、React NativeはJavaScriptトランスパイラーBabelを使用するため、ECMAScript 2015+(ECMAScript 6)構文を使用できます。 ECMAScript 2015+構文を使用する必要はありませんが、すべての公式の例とサードパーティのモジュールがそれを採用しているため、ECMAScript2015+構文を使用することを強くお勧めします。 React Nativeがパッケージ化とトランスパイルのプロセスを処理しているため、アプリケーションコードとサードパーティのモジュールは、ツールを自分で構成しなくてもこれらの機能を利用できます。
要約すると、React Nativeは、モバイル開発に対するReact中心の意見のあるアプローチですが、Cordovaを使用すると、WebテクノロジーをWebViewシェル内にバンドルできます。
ネイティブルックアンドフィール
ユーザーにとって重要なことの1つは、アプリケーションのネイティブなルックアンドフィールを持つことです。 Cordovaアプリケーションは通常、単純なWebアプリケーションであるため、最初は奇妙に感じることがいくつかあります。 問題は、タップ領域での視覚的なフィードバックの欠落から、ネイティブアプリケーションのように滑らかに感じられないスクロール、タップイベントでの300ミリ秒の遅延までさまざまです。 これらすべての問題に対する解決策はありますが、Cordovaアプリケーションをネイティブアプリケーションにできるだけ近づけたい場合は、追加の作業が必要になる可能性があることを覚えておく必要があります。 コルドバでは、ネイティブコントロールにアクセスできません。 ネイティブのルックアンドフィールが必要な場合は、2つのオプションがあります。ボタンや入力要素などのネイティブコントロールをHTMLとCSSで再作成するか、これらのネイティブコントロールに直接アクセスするネイティブモジュールを実装します。 これは、自分で行うことも、IonicやOnsenUIなどのサードパーティライブラリを使用して行うこともできます。 OSのアップデートが発生したときに、それらを最新の状態に保つことが重要であることに注意してください。 iOS 7が導入されたときに起こったように、モバイルオペレーティングシステムの外観が一新されることがあります。 適応できないアプリを使用すると、ユーザーはエクスペリエンスを利用できなくなります。 また、ネイティブ側に接続するCordovaプラグインを含めることもできます。 最も完全なネイティブコントロールの1つは、MicrosoftのAceライブラリです。
一方、React Nativeを使用すると、すぐに使用できるネイティブコントロールとインタラクションにアクセスできます。 Text
、 TextInput
、 Slider
などのコンポーネントは、ネイティブの対応するコンポーネントにマップされます。 一部のコンポーネントはすべてのプラットフォームで使用できますが、他のコンポーネントは特定のプラットフォームでのみ機能します。 アプリケーションにネイティブのルックアンドフィールを持たせたいほど、この特定のプラットフォームでのみ使用可能なコンポーネントを使用する必要があり、コードベースが分岐します。 マインドタッチのインタラクションとジェスチャーもReactNativeの一部です。
パフォーマンスの比較
Cordovaが自由に使用できるのはWebViewのみであるため、WebViewの制限に縛られています。 たとえば、4.0バージョンに続いて、AndroidはついにデフォルトのWebViewとして(はるかに高速な)Chromeエンジンの使用を開始しました。 iOSを使用している間、デフォルトのWebViewエンジン内で実行されているアプリケーションは、Safariモバイルブラウザーの同じアプリケーションよりも大幅に低速でした。 さらに、JavaScriptはシングルスレッドであるため、アプリケーションコードで多くのことが行われていると、問題が発生する可能性があります。 これらの制限によりアニメーションが遅くなり、アプリケーションの応答性が期待どおりに低下する可能性があります。 私たちがあちこちで採用できるいくつかのトリックがあるかもしれませんが、結局、私たちはモバイルブラウザの制限に縛られています。

React Nativeは複数のスレッドを利用するため、レンダリングUI要素は独自のスレッドで実行されます。 Reactコンポーネントはネイティブビューにリンクしているため、JavaScriptはReactNativeで手間のかかる作業を行っていません。
開発者ワークフロー
Cordovaは、新しいプロジェクトテンプレートを作成し、シミュレーターでアプリケーションを起動し、実稼働モードで実際のデバイス用のアプリケーションを構築するためのコマンドラインユーティリティを提供します。 ほとんどの場合、私たちはデスクトップブラウザでアプリケーションを開発しており、後でモバイルアプリケーションとしてバンドルする可能性があります。 コルドバが提供する自由を利用して、開発ワークフローに自分たちで取り組む必要があります。 デバイスにライブリロードが必要な場合は、自分で実装する必要があります。 Cordovaアプリケーションをデバッグするには、Webサイトのデバッグに使用したのと同じ原則を適用します。 たとえば、iOSでは、モバイルデバイスをUSB経由で接続し、Safariとその開発者ツールを開きます。
React Nativeは、同様のコマンドラインインターフェイスを提供し、Web開発者に馴染みのある開発ワークフローを提供します。 箱から出してライブリロードを取得します。 Reactコンポーネントを変更すると、アプリケーションは変更内容をリロードします。 最もエキサイティングな機能の1つは、アプリケーションの状態を変更せずに、行ったコンポーネントの変更を部分的に再ロードするホットモジュール交換です。 実際のデバイスに接続して、実際のデバイスで期待どおりに変更が機能するかどうかを確認することもできます。 React Nativeアプリケーションは、ChromeforDesktopを使用してリモートでデバッグできます。 エラー処理はReactNativeで明らかです。 エラーが発生した場合、アプリケーションは赤い背景を表示し、スタックトレースが表示されます。 ソースマップのおかげで、エラーの正確な場所を確認できます。 それをクリックすると、選択したエディターがコードの正確な場所に開きます。
拡張性とネイティブ機能へのアクセス
JavaScriptの面では、NPMのパッケージを含む任意のJavaScriptライブラリを自由に使用できます。 ただし、React Nativeはブラウザー環境ではないため、DOMに依存するコードを利用するのは難しい場合があります。 React NativeはCommonJSおよびES2015モジュールを採用しているため、これらの形式を使用するライブラリは簡単に統合できます。
CordovaとReactNativeはどちらも、物事のネイティブ側に接続するプラグインを作成して使用する機能を備えています。 Cordovaは、独自のAPIを作成するための低レベルのAPIを提供します。これにより、多くの制御が可能になりますが、よりネイティブでJavaScriptの定型文を使用できるようになります。
仮にObjective-CでCordovaiOSプラグインを作成するとすると、次のコードスニペットのようになります。 プラグインは入力パラメータをログに記録するだけです。
#import <Cordova/CDVPlugin.h> // Create a class that inherits from CDVPlugin @interface Log : CDVPlugin - (void)log:(CDVInvokedUrlCommand*)command; @end // The actual implementation of the class we just defined @implementation Log - (void)log:(CDVInvokedUrlCommand*)command { CDVPluginResult* pluginResult = nil; // We are getting all parameters and taking the first one NSString* echo = [command.arguments objectAtIndex:0]; // We are checking for the validity of the parameters if (echo != nil && [echo length] > 0) { // We are just printing the parameter using the native log method NSLog(echo); // Let's create a result for the plugin pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsString:echo]; } // Let's send a signal back with the plugin's result [self.commandDelegate sendPluginResult:pluginResult callbackId:command.callbackId]; } @end
このモジュールを使用するには、次のJavaScriptコードが役立ちます。
window.log = function(str, callback) { cordova.exec(callback, function(err) { callback('Nothing to echo.'); }, "Log", "log", [str]); };
プラグインを使用するには、 log
関数を呼び出す必要があります。
window.log('Hello native!');
一方、React Nativeは、異なる哲学に従います。 プラグインを作成するときに、JavaScriptタイプを対応するネイティブに自動的にマップします。これにより、ネイティブコードをJavaScriptに簡単に接続できます。 ReactNativeでネイティブモジュールを作成するために必要なコードを見てみましょう。
#import "RCTBridgeModule.h" @interface Log : NSObject <RCTBridgeModule> @end @implementation Log RCT_EXPORT_MODULE(); // This makes this method available NativeModules.Log.log RCT_EXPORT_METHOD(log:(NSString *)message) { NSLog(message); } @end
React Nativeは、 RCT_EXPORT_MODULE
およびRCT_EXPORT_METHOD
の呼び出しでモジュールをバインドします。 これで、 NativeModules.Log.log
を使用して次のようにアクセスできます。
import { React } from 'react'; import { View, Text, AppRegistry, NativeModules TouchableOpacity, } from 'react-native'; // Create an App component const App = () => { // Log with our module once we tap the text const onPress = () => NativeModules.Log.log('Hello there'); return ( <View> <TouchableOpacity onPress={onPress} /> <Text>Tap me!</Text> </TouchableOpacity> </View> ); }; // Registers the `App` component as our main entry point AppRegistry.registerComponent('App', () => App);
Objective-Cを使用してiOSでモジュールを作成する方法を詳しく調べただけですが、Javaを使用してAndroid用のモジュールを作成する場合にも同じ原則が適用されます。
各プラットフォームのプロジェクトファイル内でネイティブプラグインをリンクする必要があります。 たとえばiOSの場合、これは、コンパイルされたネイティブ部分をアプリケーションにリンクし、対応するヘッダーファイルを追加する必要があることを意味します。 これは、特にネイティブモジュールが多数ある場合、長いプロセスになる可能性があります。 幸い、これは、ReactNative自体の一部となったrnpmと呼ばれるコマンドラインユーティリティを使用することで大幅に簡素化されています。
結論:ネイティブまたはコルドバに反応しますか?
React NativeとCordovaは目的が異なるため、さまざまなニーズに対応します。 したがって、すべての分野で1つのテクノロジーが他のテクノロジーよりも優れているとは言い難いです。
Cordovaを使用することで、既存のシングルページアプリケーションをさまざまなプラットフォーム用のモバイルアプリケーションにすばやく変換できますが、インタラクションを犠牲にして、必ずしも特定のプラットフォームにネイティブな感覚を持たせる必要はありません。
React Nativeを使用すると、アプリケーションのルックアンドフィールはよりネイティブになりますが、特定のターゲットプラットフォーム用にコードの一部を再実装する必要があります。 すでにReactに手を出していて、モバイルアプリケーションの開発に興味がある場合、ReactNativeは自然な拡張機能のように感じます。