Das Duell: React Native vs. Cordova

Veröffentlicht: 2022-03-11

Da Smartphones und mobile Anwendungen immer beliebter werden, haben Webentwickler nach Möglichkeiten gesucht, mobile Anwendungen mit JavaScript zu erstellen. Diese Popularität führte zur Entwicklung vieler JavaScript-Frameworks, die native Anwendungen auf Mobilgeräten ausführen können. Derzeit sind Cordova und React Native die beliebtesten Optionen. Cordova unterstützt die mobilen Plattformen iOS, Android und Windows Phone. Bei React Native hingegen sind Android, iOS und UWP Ziele für Entwickler. (UWP steht für Universal Windows Platform, die Plattform von Microsoft, mit der dieselbe Anwendung auf Windows Phone 10 Mobile, XBox One und Windows 10 ausgeführt werden kann.)

Von der Oberfläche sieht es so aus, als würden React Native und Cordova den gleichen Raum einnehmen. Wie bei allen Technologien gibt es jedoch Aspekte, bei denen die eine glänzt und die andere zu kurz kommt. Um also ein besseres Bild von jeder Technologie zu bekommen und ihre Vorteile und Fallstricke kennenzulernen, werden wir in die Details jeder Technologie eintauchen und sie über verschiedene Disziplinen hinweg vergleichen.

Unterschiede in der Philosophie

Es ist wichtig, sich daran zu erinnern, dass sich der Slogan von React Native „Einmal lernen, überall schreiben“ von dem üblichen plattformübergreifenden Mantra „Einmal schreiben, überall ausführen“ unterscheidet. Das führt zu zwei Dingen: Erstens können wir unsere bestehende React-Codebasis nicht einfach aus unserem Webprojekt nehmen und sie mit wenigen Klicks in eine mobile Anwendung verwandeln. React und React Native teilen jedoch viele Schlüsselkonzepte, wobei ein Beispiel ihre Komponentensysteme sind, und daher fühlt sich React Native sofort vertraut an. Während React viele Ähnlichkeiten mit React Native aufweist, gibt es einige grundlegende Unterschiede, die von der Art und Weise reichen, wie Stylesheets gehandhabt werden, bis hin zu den Arten von Komponenten, die wir verwenden können.

Zweitens sind wir möglicherweise nicht in der Lage, React Native-Code zu teilen, wenn wir auf verschiedene Plattformen abzielen. Dies geschieht, wenn wir lieber möchten, dass sich Elemente der Benutzeroberfläche nativ für ihre spezifische Plattform verhalten, was dem Benutzer wiederum ein besseres Erlebnis und ein nativeres Gefühl für die App bietet. Ein offensichtliches Beispiel ist das Schubladenmenü in Android-Apps, das in iOS-Apps sehr ungewöhnlich ist.

Cordova teilt diese Philosophie nicht. Es ist nicht ungewöhnlich, mit der Entwicklung einer reinen Webanwendung zu beginnen, sie später als Cordova-Anwendung zu bündeln und so viel Code wie möglich für alle (mobilen) Plattformen wiederzuverwenden, auf die wir abzielen möchten.

Entwicklungsfreiheit

Auf mobilen Geräten führt Cordova eine Single-Page-Anwendung innerhalb des integrierten mobilen Webbrowsers namens WebView aus und umschließt diese dann als native Anwendung. Während es von außen wie eine native Anwendung aussieht, läuft unser Webcode innerhalb der mobilen Browser-Engine. Das bedeutet für uns, dass wir nicht an eine bestimmte Bibliothek oder ein bestimmtes Framework gebunden sind. Wenn wir Vanilla JavaScript, jQuery, Angular oder irgendetwas anderes verwenden, könnte jede dieser Optionen mit Cordova in einer mobilen Anwendung gebündelt werden. Cordova drängt sich unserem Technologie-Stack nicht auf. Solange wir eine index.html -Datei haben, können wir loslegen. Ein einfaches Beispiel wäre das folgende Code-Snippet:

 <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>

Dieses Beispiel bedeutet, dass wir so ziemlich alles verwenden können, was wir wollen, z. B. die Verwendung eines Paketmanagers wie NPM oder Bower, die Verwendung eines Transpilers wie Babel, CoffeeScript oder TypeScript, eines Bundlers wie Webpack oder Rollup oder etwas ganz anderes. Es spielt keine Rolle, solange das Ergebnis eine index.html -Datei ist, die alle benötigten JavaScript- und Stylesheets lädt.

React Native baut, wie der Name schon sagt, auf React auf. Es ist wichtig zu verstehen, dass der React-Teil in React Native eine seiner Kernfunktionen ist. Wenn Sie kein Fan der deklarativen Natur von React sind, einschließlich JSX, seiner Komponentenisierung und seines Datenflusses, werden Sie wahrscheinlich mit React Native nicht glücklich sein. Während sich React Native React-Entwicklern sofort vertraut anfühlt, gibt es auf den ersten Blick einige Unterschiede, an die man sich erinnern sollte. Mit React Native haben wir kein HTML oder CSS. Stattdessen konzentriert sich diese Technologie auf die JavaScript-Seite. Als Alternative zu CSS werden Stile inline geschrieben, und Flexbox ist das Standardstilmodell.

Die meisten Barebones von React Native würden diesem Beispiel ähneln:

 // 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);

React Native hat einen eigenen Packager. Es bündelt alle JavaScript-Dateien in einer riesigen Datei, die dann von JavaScriptCore, der JavaScript-Engine von Apple, verarbeitet und ausgeführt wird. JavaScriptCore wird auf iOS und Android verwendet, während ChakraCore React Native UWP-Anwendungen unterstützt. Standardmäßig verwendet React Native den JavaScript-Transpiler Babel, wodurch wir die Syntax von ECMAScript 2015+ (ECMAScript 6) verwenden können. Obwohl es nicht notwendig ist, die ECMAScript 2015+-Syntax zu verwenden, wird sie definitiv empfohlen, da alle offiziellen Beispiele und Module von Drittanbietern sie umfassen. Da React Native sich um den Paketierungs- und Transpilierungsprozess kümmert, können unser Anwendungscode und Module von Drittanbietern diese Funktionen nutzen, ohne die Tools für uns selbst konfigurieren zu müssen.

Zusammenfassend lässt sich sagen, dass React Native ein React-zentrierter, rechthaberischer Ansatz für die mobile Entwicklung ist, während Cordova es uns ermöglicht, Webtechnologien innerhalb der WebView-Shell zu bündeln.

Natives Look-and-Feel

Eine Sache, die Benutzern wichtig ist, ist ein natives Erscheinungsbild einer Anwendung. Da Cordova-Anwendungen normalerweise einfache Webanwendungen sind, gibt es einige Dinge, die sich zunächst seltsam anfühlen könnten. Die Probleme können von fehlendem visuellem Feedback in Berührungsbereichen über Scrollen, das sich nicht so seidenweich anfühlt wie in nativen Anwendungen, bis hin zu einer Verzögerung von 300 Millisekunden bei Berührungsereignissen reichen. Obwohl es Lösungen für all diese Probleme gibt, sollten wir bedenken, dass wir möglicherweise zusätzliche Anstrengungen unternehmen müssen, wenn wir möchten, dass sich unsere Cordova-Anwendung so nah wie möglich an nativen Anwendungen anfühlt. In Cordova haben wir keinen Zugriff auf native Steuerelemente. Wenn wir ein natives Erscheinungsbild haben möchten, bleiben uns zwei Möglichkeiten: Entweder die nativen Steuerelemente wie Schaltflächen und Eingabeelemente mit HTML und CSS neu erstellen oder native Module implementieren, die direkt auf diese nativen Steuerelemente zugreifen. Wir könnten dies selbst tun oder eine Bibliothek eines Drittanbieters wie Ionic oder Onsen UI verwenden. Beachten Sie, dass es wichtig ist, sie mit Betriebssystem-Updates auf dem Laufenden zu halten, sobald sie erscheinen. Manchmal erhält das Aussehen eines mobilen Betriebssystems ein Facelifting, wie es bei der Einführung von iOS 7 der Fall war. Eine App zu haben, die nicht angepasst werden kann, wird Benutzer aus der Erfahrung herausnehmen. Wir könnten auch auf Cordova-Plugins zurückgreifen, die uns mit der nativen Seite der Dinge verbinden. Eine der vollständigsten nativen Steuerelemente ist die Ace-Bibliothek von Microsoft.

Mit React Native hingegen haben wir Zugriff auf native Steuerelemente und Interaktionen out of the box. Komponenten wie Text , TextInput oder Slider werden ihren nativen Gegenstücken zugeordnet. Während einige Komponenten für alle Plattformen verfügbar sind, funktionieren andere Komponenten nur auf bestimmten Plattformen. Je mehr wir möchten, dass unsere Anwendung ein natives Erscheinungsbild hat, desto mehr müssen wir Komponenten verwenden, die nur für diese spezielle Plattform verfügbar sind, und desto mehr weicht unsere Codebasis ab. Mind-Touch-Interaktionen und -Gesten sind ebenfalls Teil von React Native.

Leistung vergleichen

Da Cordova nur über ein WebView verfügt, sind wir an die Grenzen des WebView gebunden. Zum Beispiel begann Android nach seiner Version 4.0 endlich damit, die (viel schnellere) Chrome-Engine als Standard-WebView zu verwenden. Während bei iOS die Anwendung, die in der Standard-WebView-Engine ausgeführt wurde, lange Zeit erheblich langsamer war als dieselbe Anwendung im mobilen Safari-Browser. Da JavaScript Singlethreading ist, können außerdem Probleme auftreten, wenn in unserem Anwendungscode zu viele Dinge passieren. Diese Einschränkungen führen zu langsamen Animationen, und unsere Anwendung fühlt sich möglicherweise nicht so reaktionsschnell an, wie wir es uns wünschen. Auch wenn wir hier und da ein paar Tricks anwenden können, sind wir letztendlich an die Grenzen des mobilen Browsers gebunden.

React Native verwendet mehrere Threads, wodurch UI-Elemente in einem eigenen Thread ausgeführt werden. Da React-Komponenten mit nativen Ansichten verlinken, übernimmt JavaScript in React Native nicht die schwere Arbeit.

Entwickler-Workflow

Cordova bietet ein Befehlszeilendienstprogramm zum Erstellen neuer Projektvorlagen, zum Starten der Anwendung im Simulator und zum Erstellen der Anwendung für das eigentliche Gerät in einem Produktionsmodus. Meistens entwickeln wir die Anwendung auf einem Desktop-Browser und können sie später als mobile Anwendung bündeln. Mit der Freiheit, die Cordova bietet, müssen wir den Entwicklungsworkflow selbst angehen. Wenn wir Live-Nachladen auf dem Gerät wollen, müssen wir es selbst implementieren. Um Cordova-Anwendungen zu debuggen, wenden wir die gleichen Prinzipien an, die zum Debuggen einer Website verwendet werden. In iOS würden wir beispielsweise unser mobiles Gerät über USB anschließen, Safari und seine Entwicklertools öffnen.

React Native bietet eine ähnliche Befehlszeilenschnittstelle und bietet einen Entwicklungsworkflow, der Webentwicklern vertraut ist. Wir bekommen Live-Nachladen aus der Box. Sobald wir eine React-Komponente ändern, wird unsere Anwendung mit den von uns vorgenommenen Änderungen neu geladen. Eines der aufregendsten Features ist Hot Module Replacement, bei dem die von uns vorgenommenen Änderungen in der Komponente teilweise neu geladen werden, ohne den Status der Anwendung zu ändern. Wir könnten sogar eine Verbindung zu einem tatsächlichen Gerät herstellen und sehen, ob unsere Änderungen so funktionieren, wie wir es auf einem echten Gerät erwarten würden. Unsere React Native-Anwendungen können mit Chrome for Desktop remote debuggt werden. Die Fehlerbehandlung ist in React Native offensichtlich; Wenn wir auf einen Fehler stoßen, zeigt unsere Anwendung einen roten Hintergrund und der Stack-Trace wird angezeigt. Dank Sourcemaps können wir den genauen Ort des Fehlers sehen. Wenn wir darauf klicken, öffnet sich der Editor unserer Wahl genau an der Stelle des Codes.

Erweiterbarkeit und Zugriff auf die nativen Funktionen

Auf der JavaScript-Seite steht es uns frei, jede JavaScript-Bibliothek zu verwenden, einschließlich Paketen von NPM. Da React Native jedoch keine Browserumgebung ist, können wir es schwierig finden, Code zu verwenden, der auf DOM angewiesen ist. React Native umfasst CommonJS- und ES2015-Module, sodass alle Bibliotheken, die diese Formate verwenden, einfach zu integrieren sind.

Sowohl Cordova als auch React Native haben die Möglichkeit, Plugins zu erstellen und zu verwenden, die eine Verbindung zur nativen Seite der Dinge herstellen. Cordova bietet eine Low-Level-API zum Erstellen unserer eigenen, die uns viel Kontrolle gibt, aber zur Verwendung von mehr nativen und JavaScript-Boilerplates führt.

Wenn wir hypothetisch ein Cordova-iOS-Plug-in in Objective-C schreiben würden, könnte es wie das nächste Code-Snippet aussehen. Unser Plugin protokolliert nur den Eingabeparameter.

 #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

Um das Modul zu verwenden, hilft dieser JavaScript-Code:

 window.log = function(str, callback) { cordova.exec(callback, function(err) { callback('Nothing to echo.'); }, "Log", "log", [str]); };

Um das Plugin zu verwenden, müssen wir nur die log aufrufen:

 window.log('Hello native!');

React Native hingegen folgt einer anderen Philosophie; Es ordnet JavaScript-Typen beim Schreiben von Plugins automatisch seinen nativen Gegenstücken zu, was es einfacher macht, nativen Code mit JavaScript zu verbinden. Werfen wir einen Blick auf ein Stück Code, das zum Erstellen eines nativen Moduls mit React Native erforderlich ist:

 #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 bindet das Modul für uns mit den Aufrufen RCT_EXPORT_MODULE und RCT_EXPORT_METHOD . Wir können jetzt mit NativeModules.Log.log darauf zugreifen:

 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);

Während wir uns nur die Erstellung eines Moduls in iOS mit Objective-C genau angesehen haben, gelten die gleichen Prinzipien für die Erstellung eines Moduls für Android mit Java.

Wir müssen native Plugins innerhalb der Projektdateien für jede Plattform verknüpfen. Bei iOS bedeutet dies beispielsweise, dass wir den kompilierten nativen Teil mit unserer Anwendung verknüpfen und die entsprechenden Header-Dateien hinzufügen müssen. Dies kann ein langer Prozess sein, insbesondere wenn viele native Module vorhanden sind. Glücklicherweise wird dies erheblich vereinfacht, indem ein Befehlszeilenprogramm namens rnpm verwendet wird, das Teil von React Native selbst geworden ist.

Fazit: Native oder Cordova reagieren?

React Native und Cordova haben unterschiedliche Zwecke und werden daher unterschiedlichen Bedürfnissen gerecht. Daher ist es schwer zu sagen, dass eine Technologie über alle Disziplinen hinweg besser ist als die andere.

Durch die Verwendung von Cordova können Sie Ihre vorhandene Einzelseitenanwendung schnell in eine mobile Anwendung für verschiedene Plattformen umwandeln, auf Kosten von Interaktionen, die nicht unbedingt das native Gefühl für ihre spezifische Plattform haben.

Mit React Native haben Anwendungen ein nativeres Erscheinungsbild, jedoch auf Kosten der Neuimplementierung von Codeteilen für bestimmte Zielplattformen. Wenn Sie sich bereits mit React beschäftigt haben und daran interessiert sind, mobile Anwendungen zu entwickeln, fühlt sich React Native wie eine natürliche Erweiterung an.

Siehe auch: Cold Dive into React Native: Ein Anfänger-Tutorial