Wielokrotnie już mieliśmy do czynienia z klientami, którzy chcą stworzenia dla nich aplikacji mobilnych na Androida i iOS-a, jednak gdy otrzymują wycenę, są nią załamani — znacznie bowiem przekracza ona budżet, jakim dysponują. W takich sytuacjach proponujemy klientom stworzenie aplikacji w technologii React Native. To jednak spotyka się z podejrzliwością — jak to jest, że początkowa wycena była taka wysoka, a teraz nagle możemy zaoferować coś o wiele tańszego? Na czym oszczędzamy? I dlaczego od razu nie zaproponowaliśmy tej technologii? Na te pytania nie ma ogólnej odpowiedzi. Możemy jedynie wyjaśnić, czym React Native jest, a czym nie jest, jakie są plusy i minusy tej technologii.
Wysoki koszt tworzenia natywnych aplikacji nie wziął się znikąd. Dla większości aplikacji trzeba pisać wszystko dwukrotnie, jeśli chce się, aby użytkownicy iOS-a i Androida mogli cieszyć się aplikacją. Na iOS-ie programujemy zwykle w językach Objective-C lub Swift, na Androidzie w Javie lub Kotlinie. Jedynie w pewnych wypadkach można na obu platformach wykorzystać tę samą bibliotekę pisaną w języku C czy C++. W zamian jednak można korzystać ze wszystkich natywnych komponentów interfejsu użytkownika, działających daleko szybciej i płynniej, niż jest to możliwe dla aplikacji uruchamianych w przeglądarce. Można też korzystać z funkcji urządzenia mobilnego zazwyczaj dla aplikacji przeglądarkowych niedostępnych.
Chciałoby się mieć ciastko i zjeść ciastko
Zaczęło się wszystko od Facebooka. W 2012 roku Mark Zuckerberg przyznał, że postawienie na standard HTML5 jako uniwersalną platformę aplikacji dla urządzeń mobilnych skończyło się porażką. Pomimo zapewnień producentów przeglądarek i niszowych systemów takich jak BlackBerry OS czy Firefox OS, aplikacje w HTML5 nigdy nawet się nie zbliżyły w możliwościach i wygodzie użytkowania do aplikacji natywnych, pisanych na Androida i iOS-a. Zuckerberg obiecał więc, że w przyszłości Facebook znajdzie sposób, aby lepiej działać na urządzeniach mobilnych.
Jednocześnie jeden z deweloperów Facebooka, Jordan Walke, znalazł sposób na generowanie natywnego elementu interfejsu użytkownika systemu iOS z działającego w tle wątku kodu napisanego w JavaScripcie. Po kilku dniach intensywnych prac powstał z tego prototyp pozwalający na generowanie dowolnych natywnych elementów interfejsu w kodzie pisanym na bazie biblioteki React.js. Biblioteka ta wykorzystywana była już wcześniej przez Facebooka do szybkiego tworzenia interfejsów użytkownika aplikacji webowych.
Pierwsza wersja React Native została zaprezentowana w 2015 roku i szybko stała się jednym z najgorętszych tematów w branży programistycznej. Połączono tu zalety aplikacji webowych (szybki rozwój, łatwość programowania), z zaletami aplikacji natywnych (szybki dostęp do elementów i animacji interfejsu użytkownika).
W efekcie wystarczy raz napisać kod w JavaScripcie, a dzięki „magii” React Native dostanie się aplikację z natywnymi elementami dla iOS-a (od wersji 8) i Androida (od wersji 4.1), którą można przenieść do Apple App Store i Google Play Store. No może nie do końca w czystym JavaScripcie… ogromną rolę odgrywa tu rozszerzenie JSX, które pozwala zdefiniować rysowanie natywnych komponentów w sposób analogiczny do tego znanego z HTML.
Jak React Native rysuje interfejsy?
Aby zrozumieć, jak działa technologia React Native na systemie mobilnym, trzeba przypomnieć sobie wpierw mechanizm Virtual DOM z biblioteki React.js. Działa on jak warstwa pomiędzy opisem tego, jak interfejs powinien wyglądać, a pracą wykonaną w celu faktycznego renderowania interfejsu na stronie internetowej. Interaktywny interfejs użytkownika na stronie internetowej jest bowiem możliwy tylko poprzez modyfikowanie na bieżąco tzw. obiektowego modelu dokumentu (DOM) przeglądarki
W wypadku React Native na urządzeniu mobilnym nie modyfikuje się oczywiście DOM przeglądarki. React Native wywołuje interfejsy Objective-C, aby rysować komponenty na iOS-ie lub interfejsy Javy, aby rysować komponenty na Androidzie. Wywołanie to możliwe jest dzięki specjalnemu mostkowi, zapewniającemu interfejs do natywnych elementów platformy. Komponenty wzięte z Reacta zwracają więc opis jak interfejs powinien wyglądać, a React Native tłumaczy ten opis na zgodny z iOS-em czy Androidem.
Dzięki temu proste <View> (odpowiednik <div> z HTML) zamienia się na iOS-ie w natywną kontrolkę UILabel lub UITextView, a na Androidzie w natywną kontrolkę TextView.
Od technologii webowych do technologii natywnych
Niektórzy mogą zauważyć, że takie podejście łączące technologie webowe z urządzeniami mobilnymi już było. Chodzi oczywiście o technologię Apache Cordova, kiedyś znaną pod nazwą PhoneGap. Cordova jest czymś w rodzaju natywnego kontenera wokół aplikacji webowej, który zapewnia tej aplikacji interfejsy normalnie przez przeglądarkę niedostępne. Jak się jednak bliżej przyjrzymy, to zauważymy, że React Native nic wspólnego z Cordovą nie ma. Aplikacja napisana w React Native nie jest stroną internetową, z kolei aplikacja w kontenerze Cordova nie ma żadnego dostępu do natywnych elementów interfejsu iOS-a czy Androida. Różnicę w wydajności i płynności działania zobaczy nawet laik.
Skoro więc React Native jest tak wydajny i szybki, to czemu w ogóle nie oszczędzać pieniędzy, nie zaprzestać pisania natywnego oprogramowania na systemy mobilne? Odpowiedź jest tu prosta — ponieważ jest on wydajny i szybki tylko pod względem interfejsu użytkownika.
Nie można bowiem zapominać, że cała logika biznesowa jest napisana w JavaScripcie, który nie jest kompilowany do kodu natywnego, lecz jest interpretowany na bieżąco, w trakcie interakcji z natywnym interfejsem na urządzeniu. Środowisko uruchomieniowe JavaScriptu jest zaś póki co jednowątkowe, nie pozwala wykorzystać wielordzeniowych mobilnych procesorów.
Jeśli więc aplikacja potrzebuje wydajnej, wielowątkowej logiki biznesowej, w React Native będzie działała znacznie bardziej ślamazarnie. Tak samo też, im więcej tych interakcji logiki aplikacji z interfejsem użytkownika, tym bardziej ograniczy to wydajność działania. Istnieją co prawda metody zwiększenia wydajności — np. pisanie wymagających elementów aplikacji w języku C/C++, ale wymagać to będzie budowania dla nich specjalnych pomostów, co wiąże się z dodatkowymi kosztami.
Pewnym ograniczeniem jest także to, że nie wszystkie widoki dostępne w React Native są faktycznie natywnymi widokami z platformy. Mówi się, że pełną zgodność platforma ta osiągnie wraz z wydaniem wersji 1.0 (póki co, w sierpniu 2018 r. jest dostępna wersja 0.56), ale nikt nie wie kiedy to nastąpi. Trzeba pamiętać, że to platforma Facebooka, rozwijana przede wszystkim z myślą o aplikacjach mobilnych Facebooka.
Kiedy warto sięgnąć po React Native?
Jeśli aplikację mobilną trzeba stworzyć szybko, przy ograniczonym budżecie, a zarazem aplikacja nie jest jakoś bardzo skomplikowana — wybór React Native jest bardzo dobrym pomysłem. Z zadaniem takim poradzi sobie każdy doświadczony programista JavaScriptu, który zechce się nauczyć procedur publikacji aplikacji w sklepach Google czy Apple.
Z drugiej jednak strony, jeśli aplikacja jest rozbudowana i wymagająca, gdzie niewiele kodu można współdzielić, a wiele pracy będzie przy budowie modułów pomostowych, lepiej od początku programować natywnie na Androida i iOS-a. Trzeba też pamiętać, że React Native szybko się rozwija i zmienia, a to oznacza, że utrzymanie napisanych w nim aplikacji może być droższe niż aplikacji napisanych w Objective-C czy Javie. Po prostu w nowszych wersjach React Native wiele rzeczy może działać zupełnie inaczej, niż działało wcześniej — i to wszystko trzeba będzie ogarnąć.
Atuty React Native
- jeden kod dla wielu platform (w teorii można wyjść poza iOS-a i Androida, tworząc nowy mostek dla kolejnej platformy),
- jeden zespół programistów,
- szybki rozwój aplikacji w technologiach webowych,
- proste zsynchronizowanie rozwoju i aktualizacji aplikacji między platformami mobilnymi,
- bazowanie na React.js, który jest naprawdę dobrym frameworkiem programistycznym,
- niższa cena tworzenia aplikacji mobilnej,
Ograniczenia React Native
- konieczność pisania logiki biznesowej w JavaScripcie,
- ograniczona wydajność jednowątkowego środowiska uruchomieniowego JavaScriptu,
- wysoki koszt utrzymania i rozwoju aplikacji w związku z szybkim rozwojem frameworka,
- ograniczona zgodność z wytycznymi projektowania interfejsów Apple i Google.
Originally published at Matsuu Mobile Application Development and Design Studio.