Pojedynek: React Native kontra Cordova

Opublikowany: 2022-03-11

W związku z rosnącą popularnością smartfonów i aplikacji mobilnych, twórcy stron internetowych szukali sposobów na tworzenie aplikacji mobilnych przy użyciu JavaScript. Ta popularność zaowocowała opracowaniem wielu frameworków JavaScript zdolnych do uruchamiania aplikacji podobnych do natywnych na urządzeniach mobilnych. Obecnie najpopularniejsze są Cordova i React Native. Cordova obsługuje platformy mobilne iOS, Android i Windows Phone. Z drugiej strony w przypadku React Native systemy Android, iOS i platforma UWP są celami dla programistów. (UWP to skrót od Universal Windows Platform, platforma firmy Microsoft, która umożliwia uruchamianie tej samej aplikacji w systemie Windows Phone 10 Mobile, XBox One i Windows 10.)

Na pierwszy rzut oka wydaje się, że React Native i Cordova zajmują tę samą przestrzeń. Jednak, podobnie jak w przypadku wszystkich technologii, są aspekty, w których jeden błyszczy, a drugi nie. Aby więc uzyskać lepszy obraz każdej technologii oraz poznać jej zalety i pułapki, zagłębimy się w szczegóły każdej z nich i porównamy je w różnych dyscyplinach.

Różnice w filozofii

Należy pamiętać, że slogan React Native „Ucz się raz, pisz gdziekolwiek” różni się od zwykłej mantry międzyplatformowej: „Napisz raz, biegnij gdziekolwiek”. Prowadzi to do dwóch rzeczy: po pierwsze, nie możemy po prostu wziąć naszej istniejącej bazy kodu React z naszego projektu internetowego i przekształcić go w aplikację mobilną za pomocą zaledwie kilku kliknięć. Jednak React i React Native dzielą wiele kluczowych koncepcji, a jednym z przykładów są ich systemy składowe, w wyniku czego React Native jest od razu znajomy. Chociaż React dzieli wiele podobieństw z React Native, istnieją pewne podstawowe różnice, które obejmują sposób obsługi arkuszy stylów i typ komponentów, których możemy użyć.

Po drugie, możemy nie być w stanie udostępniać kodu React Native, gdy kierujemy się na różne platformy. Dzieje się tak, gdy wolimy, aby elementy interfejsu użytkownika zachowywały się natywnie dla ich konkretnej platformy, co z kolei zapewnia użytkownikowi lepsze wrażenia i bardziej natywny charakter aplikacji. Oczywistym przykładem jest boczne menu szuflady w aplikacjach na Androida, które jest bardzo rzadkie w aplikacjach na iOS.

Cordova nie podziela tej filozofii. Często zdarza się, że zaczyna się tworzenie czystej aplikacji internetowej, a następnie łączy ją jako aplikację Cordova i ponownie wykorzystuje jak najwięcej kodu dla wszystkich (mobilnych) platform, na które chcemy kierować reklamy.

Swoboda rozwoju

Na urządzeniach mobilnych Cordova uruchamia jednostronicową aplikację w zintegrowanej mobilnej przeglądarce internetowej o nazwie WebView, a następnie pakuje ją jako aplikację natywną. Choć z zewnątrz wygląda jak aplikacja natywna, nasz kod WWW działa w silniku przeglądarki mobilnej. Dla nas oznacza to, że nie jesteśmy związani z konkretną biblioteką lub frameworkiem. Jeśli używamy waniliowego JavaScript, jQuery, Angular lub czegokolwiek innego, każda z tych opcji może zostać dołączona do aplikacji mobilnej z Cordova. Cordova nie nakłada na nasz stos technologii. Dopóki mamy plik index.html , dobrze jest iść. Prostym przykładem może być następujący fragment kodu:

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

Ten przykład oznacza, że ​​możemy użyć prawie wszystkiego, czego pragniemy, na przykład za pomocą menedżera pakietów, takiego jak NPM lub Bower, używając transpilera, takiego jak Babel, CoffeeScript lub TypeScript, pakietu, takiego jak Webpack lub Rollup, lub czegoś zupełnie innego. Nie ma to znaczenia, o ile wynikiem jest plik index.html , który ładuje cały potrzebny JavaScript i arkusze stylów.

React Native, jak sama nazwa wskazuje, opiera się na React. Ważne jest, aby zrozumieć, że część React w React Native jest jedną z jego podstawowych funkcji. Jeśli nie jesteś fanem deklaratywnej natury Reacta, w tym JSX, jego komponentów i przepływu danych, prawdopodobnie nie będziesz zadowolony z React Native. Chociaż React Native od razu wydaje się znajomy programistom React, na pierwszy rzut oka istnieją pewne różnice, o których należy pamiętać. W React Native nie mamy kodu HTML ani CSS. Zamiast tego ta technologia koncentruje się na stronie JavaScript. Jako alternatywę dla CSS, style są pisane inline, a Flexbox jest domyślnym modelem stylizacji.

Najbardziej prosta aplikacja React Native wyglądałaby podobnie do tego przykładu:

 // 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 ma własny paker. Łączy wszystkie pliki JavaScript w jeden gigantyczny plik, który jest następnie zużywany i wykonywany przez JavaScriptCore, silnik JavaScript firmy Apple. JavaScriptCore jest używany na iOS i Androidzie, podczas gdy ChakraCore obsługuje aplikacje React Native UWP. Domyślnie React Native używa transpilera JavaScript Babel, co pozwala nam używać składni ECMAScript 2015+ (ECMAScript 6). Chociaż nie jest konieczne używanie składni ECMAScript 2015+, zdecydowanie jest to zalecane, ponieważ wszystkie oficjalne przykłady i moduły stron trzecich obejmują ją. Ponieważ React Native zajmuje się procesem pakowania i transpilacji, nasz kod aplikacji i moduły innych firm mogą korzystać z tych funkcji bez konieczności samodzielnego konfigurowania narzędzi.

Podsumowując, React Native to oparte na React uparty podejście do rozwoju mobilnego, podczas gdy Cordova pozwala nam łączyć technologie internetowe w powłoce WebView.

Natywny wygląd i styl

Jedną z rzeczy, która jest ważna dla użytkowników, jest posiadanie natywnego wyglądu aplikacji. Ponieważ aplikacje Cordova są zwykle prostymi aplikacjami internetowymi, jest kilka rzeczy, które na początku mogą wydawać się dziwne. Problemy mogą obejmować brak wizualnej informacji zwrotnej w obszarach dotknięcia, przewijanie, które nie jest tak płynne, jak w natywnych aplikacjach, aż po 300 milisekundowe opóźnienie w zdarzeniach dotknięcia. Chociaż istnieją rozwiązania dla wszystkich tych problemów, powinniśmy pamiętać, że być może będziemy musieli włożyć dodatkowy wysiłek, jeśli chcemy, aby nasza aplikacja Cordova była jak najbardziej zbliżona do aplikacji natywnych. W Kordowie nie mamy dostępu do żadnych natywnych kontrolek. Jeśli chcemy mieć natywny wygląd i styl, pozostają nam dwie opcje: albo ponownie utwórz natywne kontrolki, takie jak przyciski i elementy wejściowe, za pomocą HTML i CSS, albo zaimplementuj natywne moduły, które mają bezpośredni dostęp do tych natywnych kontrolek. Moglibyśmy to zrobić sami lub korzystając z biblioteki innej firmy, takiej jak Ionic lub Onsen UI. Pamiętaj, że ważne jest, aby aktualizować je w miarę pojawiania się aktualizacji systemu operacyjnego. Czasami wygląd mobilnego systemu operacyjnego ulega liftingowi, jak to miało miejsce, gdy wprowadzono iOS 7. Posiadanie aplikacji, której nie jest w stanie dostosować, odbierze użytkownikom doświadczenie. Moglibyśmy również skorzystać z wtyczek Cordova, które łączą nas z natywną stroną rzeczy. Jedną z najbardziej kompletnych natywnych kontrolek jest biblioteka Ace firmy Microsoft.

Z kolei w React Native mamy dostęp do natywnych kontrolek i interakcji po wyjęciu z pudełka. Komponenty takie jak Text , TextInput lub Slider odwzorowują swoje natywne odpowiedniki. Podczas gdy niektóre komponenty są dostępne dla wszystkich platform, inne działają tylko na określonych platformach. Im bardziej chcemy, aby nasza aplikacja miała natywny wygląd i działanie, tym bardziej musimy używać komponentów, które są dostępne tylko dla tej konkretnej platformy, a więc tym bardziej różni się nasza baza kodu. Interakcje i gesty mind touch są również częścią React Native.

Porównanie wydajności

Ponieważ Cordova ma do dyspozycji tylko WebView, jesteśmy związani ograniczeniami WebView. Na przykład, po wersji 4.0, Android w końcu zaczął używać (o wiele szybszego) silnika Chrome jako domyślnego WebView. Podczas gdy w iOS, przez długi czas aplikacja działająca w domyślnym silniku WebView była znacznie wolniejsza niż ta sama aplikacja w przeglądarce mobilnej Safari. Ponadto, ponieważ JavaScript jest jednowątkowy, możemy napotkać problemy, jeśli w kodzie aplikacji dzieje się zbyt wiele rzeczy. Te ograniczenia prowadzą do powolnych animacji, a nasza aplikacja może nie być tak responsywna, jak byśmy tego chcieli. Chociaż mogą istnieć pewne sztuczki, które możemy zastosować tu i tam, w końcu jesteśmy związani ograniczeniami przeglądarki mobilnej.

React Native wykorzystuje wiele wątków, dlatego renderuje elementy interfejsu użytkownika działające we własnym wątku. Ponieważ komponenty React łączą się z widokami natywnymi, JavaScript w React Native nie wykonuje zbyt dużego zadania.

Przepływ pracy dla programistów

Cordova oferuje narzędzie wiersza poleceń do tworzenia nowych szablonów projektów, uruchamiania aplikacji w symulatorze i budowania aplikacji dla rzeczywistego urządzenia w trybie produkcyjnym. Przez większość czasu tworzymy aplikację w przeglądarce desktopowej, a później możemy ją spakować jako aplikację mobilną. Dzięki swobodzie, jaką oferuje Cordova, musimy sami zająć się przepływem pracy programistycznej. Jeśli chcemy przeładowywać na żywo na urządzeniu, musimy to wdrożyć sami. Do debugowania aplikacji Cordova stosujemy te same zasady, które służą do debugowania strony internetowej. Na przykład w iOS połączylibyśmy nasze urządzenie mobilne przez USB, otworzyli Safari i jego narzędzia programistyczne.

React Native oferuje podobny interfejs wiersza poleceń i oferuje przepływ pracy programistyczny znany programistom internetowym. Przeładowywanie na żywo po wyjęciu z pudełka. Gdy zmienimy komponent React, nasza aplikacja ładuje się ponownie ze zmianami, które wprowadziliśmy. Jedną z najbardziej ekscytujących funkcji jest wymiana modułu na gorąco, która częściowo ponownie ładuje zmiany w wykonanym przez nas komponencie, bez zmiany stanu aplikacji. Moglibyśmy nawet połączyć się z rzeczywistym urządzeniem i sprawdzić, czy nasze zmiany działają tak, jak oczekiwalibyśmy na prawdziwym urządzeniu. Nasze aplikacje React Native można debugować zdalnie za pomocą przeglądarki Chrome na komputer. Obsługa błędów jest oczywista w React Native; jeśli natkniemy się na błąd, nasza aplikacja wyświetli czerwone tło i pokazany zostanie ślad stosu. Dzięki mapom źródłowym możemy zobaczyć dokładną lokalizację błędu. Kiedy go klikniemy, nasz wybrany edytor otworzy się w dokładnej lokalizacji kodu.

Rozszerzalność i dostęp do funkcji natywnych

Od strony JavaScript możemy używać dowolnej biblioteki JavaScript, w tym pakietów z NPM. Jednak ponieważ React Native nie jest środowiskiem przeglądarkowym, korzystanie z kodu opartego na DOM może być trudne. React Native obejmuje moduły CommonJS i ES2015, więc wszelkie biblioteki korzystające z tych formatów są łatwe do zintegrowania.

Zarówno Cordova, jak i React Native mają możliwość tworzenia i używania wtyczek, które łączą się z natywną stroną rzeczy. Cordova zapewnia niskopoziomowe API do tworzenia własnych, co daje nam dużą kontrolę, ale prowadzi do korzystania z większej liczby natywnych i JavaScript boilerplates.

Gdybyśmy mieli hipotetycznie napisać wtyczkę Cordova iOS w Objective-C, mogłaby wyglądać jak kolejny fragment kodu. Nasza wtyczka po prostu zarejestruje parametr wejściowy.

 #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

Aby skorzystać z modułu, ten fragment kodu JavaScript pomoże:

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

Aby skorzystać z wtyczki, wystarczy wywołać funkcję log :

 window.log('Hello native!');

Z drugiej strony React Native kieruje się inną filozofią; podczas pisania wtyczek automatycznie mapuje typy JavaScript na ich natywne odpowiedniki, co ułatwia łączenie natywnego kodu z JavaScript. Rzućmy okiem na fragment kodu, który jest niezbędny do stworzenia modułu natywnego za pomocą React Native:

 #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 łączy dla nas moduł z wywołaniami RCT_EXPORT_MODULE i RCT_EXPORT_METHOD . Możemy teraz uzyskać do niego dostęp za pomocą NativeModules.Log.log w następujący sposób:

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

Chociaż przyjrzeliśmy się bliżej tworzeniu modułu w iOS przy użyciu Objective-C, te same zasady obowiązują przy tworzeniu modułu dla Androida przy użyciu Javy.

Musimy połączyć natywne wtyczki w plikach projektu dla każdej platformy. Na przykład w systemie iOS oznacza to, że musimy połączyć skompilowaną część natywną z naszą aplikacją i dodać odpowiednie pliki nagłówkowe. Może to być długi proces, zwłaszcza jeśli istnieje wiele modułów natywnych. Na szczęście jest to znacznie uproszczone dzięki użyciu narzędzia wiersza poleceń o nazwie rnpm, które stało się częścią samego React Native.

Wniosek: React Native czy Cordova?

React Native i Cordova mają różne cele, więc zaspokajają różne potrzeby. Dlatego trudno powiedzieć, że jedna technologia jest lepsza od drugiej we wszystkich dyscyplinach.

Korzystając z Cordova, możesz szybko przekształcić istniejącą aplikację jednostronicową w aplikację mobilną dla różnych platform, kosztem interakcji niekoniecznie mających natywny charakter ich konkretnej platformy.

Dzięki React Native aplikacje mają bardziej natywny wygląd i działanie, ale kosztem ponownej implementacji fragmentów kodu dla określonych platform docelowych. Jeśli bawiłeś się już Reactem i interesujesz się tworzeniem aplikacji mobilnych, React Native wydaje się naturalnym rozszerzeniem.

Powiązane: Zimne nurkowanie w React Native: samouczek dla początkujących