Native, Hybrid, PWA - aplikacje mobilne XXI wieku

Aplikacje mobilne stały się naszą codziennością. Dzień zaczynamy od wyłączenia alarmu w telefonie, później przeglądamy social media, komunikujemy się przy ich pomocy, a w wolnych chwilach oglądamy śmieszne koty w aplikacji ze śmiesznymi kotami.

Jeszcze nie tak dawno temu jedyną opcją zrobienia aplikacji było nauczenie się natywnego języka wybranej platformy i napisanie w nim aplikacji. Jeżeli chcieliśmy mieć aplikację na obu platformach, wiązało się to z podwojoną ilością roboty (i wiedzy).

Dziś aplikacje mobilne można tworzyć na kilka sposobów. W dzisiejszym artykule opiszę różnice między nimi oraz pokażę, że złoty środek (niestety) nie istnieje. W związku z tym warto znać możliwości, jakie daje nam technologia, aby możliwie najlepiej dostosować rozwiązanie do swojego problemu.

Zacznijmy od pierwotnego podejścia...

Aplikacje natywne

Klasyczne podejście tworzenia aplikacji mobilnych polega na pisaniu natywnego kodu dla każdej z platform osobno. W przypadku Androida jest to Java lub Kotlin, dla iOS będzie to Swift lub Objective-C. Jak już wcześniej wspomniałem - jeżeli chcielibyśmy mieć aplikację na obu platformach, wiązałoby się to z napisaniem aplikacji dla każdego z systemów.

Aplikacje natywne są prekursorem pozostałych podejść opisanych w tym artykule. Pod kątem wydajności i możliwości technologicznych stoją na przedzie. Aplikacje hybrydowe dokładają dodatkową warstwę abstrakcji, co już na starcie oznacza, że będą nieco mniej wydajne niż te natywne.

Native przoduje również w kwestii możliwości technologicznych. Teoretycznie aplikacje hybrydowe mogą stanąć z nim na równi, ponieważ możemy pisać natywne moduły, które podpinamy do aplikacji, lecz trzeba mieć na uwadze, że wiąże się to z dodatkowym nakładem pracy. Jeżeli chodzi o PWA - nie obsługują jeszcze wszystkich modułów natywnych i zależnie od przeglądarki posiadanej na telefonie są mniej lub bardziej ograniczone.

Ważną kwestią jest też User eXperience aplikacji. Tworząc rozwiązanie natywnie, nie musimy się specjalnie martwić o zgodność z resztą systemu - jest ona narzucona przez środowisko programistyczne i poniekąd dzieje się to naturalnie. W wyniku tego użytkownicy dostają aplikację zgodną z UXem systemu, którego używają.

Zbierając powyższe wnioski - warto rozważyć stworzenie aplikacji natywnej, gdy:

  • Tworzymy złożone aplikacje wymagające wydajności (ciężkie obliczenia, gry),
  • Planujemy oprzeć logikę o natywne moduły / hardware lub integrujemy się z fizycznymi urządzeniami,
  • Chcemy zachować natywny UX.

Nowa era - React Native i Flutter

Ten dział będzie oparty o moje doświadczenia z React-Native (dalej RN). Jedynie z nim miałem do czynienia w kontekście pisania aplikacji JS tłumaczonych do kodu natywnego. Nie jestem pewny, jak wygląda ekosystem innych frameworków służących do tworzenia tego typu aplikacji.

Przy użyciu React Native / Fluttera kwestia pisania kodu nieco się zmienia - musimy go napisać tylko raz i powinien działać na wszystkich platformach. Fakt ten sprawia, że tego typu podejście jest zdecydowanie tańsze niż klasyczne. Piszemy tylko jedną aplikację, którą dostosowujemy do poszczególnych platform, zamiast tworzyć osobny produkt dla każdej z nich. W kwestii UX trzeba włożyć nieco więcej wysiłku, żeby zachować natywny UX zgodny z systemem, lecz jeżeli aplikacja sama w sobie jest intuicyjna, to najczęściej nie stanowi to problemu.

Ekosystem React Native daje wiele możliwości. Warto pamiętać, że większość paczek jest community-driven. Przy głębszym zagłębieniu się w temat okazuje się, że mniej popularne paczki często przestają być utrzymywane. Możecie znaleźć się w sytuacji, że jedyną sensowną drogą skorzystania z biblioteki będzie utworzenie forka i dopasowanie jej do swojego rozwiązania lub napisanie czegoś własnego od zera. Pamiętajcie, że problem ten dotyczy głównie mniej popularnych bibliotek, te bardziej popularne nie mają takiego problemu i są stale utrzymywane / rozwijane.

Tworzenie interfejsów jest proste i przyjemne. Większość potrzeb pokrywają biblioteki komponentów, których jest pokaźna ilość. Korzystanie z nich wygląda podobnie do podejścia znanego z web-devu. W przypadku RN jest nawet biblioteka dostarczająca komponenty imitujące te z natywnych platform (NativeBase)

Obsługa natywnych modułów w RN w większości przypadków zapewniana jest przez biblioteki stanowiące most między aplikacją RN a API natywnego modułu. Pomimo tego, przed skorzystaniem z jakiejkolwiek biblioteki polecam zwrócić uwagę na jej popularność, czy jest utrzymywana oraz, czy zaspokaja nasze wszelkie potrzeby. Dobrą regułą jest sprawdzenie, czy w ostatnim czasie na repozytorium pojawiły się nowe commity lub rozwiązania issuesów utworzonych przez użytkowników. Zdarza się, że popularne biblioteki dostarczają minimalne API, które przy niektórych rozwiązaniach może nie wystarczyć lub nie nadążają za aktualizacjami wersji RN / platform.

Bardziej złożone aplikacje mogą stanowić wyzwanie. Jeżeli okaże się, że żadna z bibliotek nie zaspokaja naszych potrzeb, może to oznaczać konieczność "ubrudzenia" sobie rąk natywnym kodem. Włączanie natywnego kodu do źródeł na pewno znajdziecie w dokumentacji frameworka (dla RN tutaj). Warto mieć świadomość, że pisząc aplikacje z użyciem RN, miejscami kod może wymagać dostosowania go do poszczególnych platform. Wiąże się to z pisaniem warunków sprawdzających, na jakim systemie działa aplikacja i pisanie obsługi dedykowanej do platformy. Nie jest to zbyt częste zjawisko, gdyż zespół RN stara się je minimalizować.

Podsumowując - skorzystanie z tego podejścia może być dobrym pomysłem, gdy:

  • Zależy nam na wysokiej wydajności,
  • Chcemy utrzymywać jeden codebase zamiast dwóch (tańsze, łatwiejsze w utrzymaniu rozwiązanie),
  • Możliwości PWA nam nie wystarczą (kwestie bezpieczeństwa lub dostępności API),
  • Znamy JS (RN) / Dart (Flutter) i chcemy wykorzystać nasze umiejętności do napisania aplikacji mobilnej.

Pamiętajcie, że aby zbudować aplikację na daną platformę musicie posiadać urządzenie lub emulator, korzystający z tego systemu.

Aplikacje hybrydowe

Są to aplikacje internetowe opakowane przez natywny komponent WebView. Podejście to pozwala na tworzenie rozwiązania przy użyciu HTMLa, CSSa i JavaScriptu. Przekłada się na to względnie niski koszt developmentu, gdyż korzystamy z podstawowych technologii webowych, a także nie musimy tworzyć rozwiązania dla każdej platformy. W dużym skrócie oznacza to, że relatywnie szybko jesteśmy w stanie stworzyć gotowe rozwiązanie, które będzie dostępne na wszystkich platformach.

Podobnie wygląda kwestia wprowadzania zmian oraz rozwoju tego typu aplikacji. Dużo łatwiej jest pozyskać osobę, która będzie w stanie pracować w oparciu o HTML / CSS / JS, niż developerów poszczególnych platform. Dzięki temu szybkie wytworzenie aplikacji jest dużo bardziej przystępne.

Niestety aplikacje hybrydowe nie są idealnym podejściem, niosą swój plecak ograniczeń. Ich największą bolączką jest to, że koniec końców, są stroną Internetową. Powoduje to, że ładują się dłużej niż aplikacje natywne oraz bardzo często wymagają połączenia z siecią, aby działać poprawnie.

Aplikacje hybrydowe borykają się również z problemami wydajnościowymi. Warstwa pośrednia w postaci WebView znacznie wpływa na możliwości tego typu aplikacji. Wykonywanie ciężkich operacji oraz animowanie widoków może spowodować, że odbije się to na UX'ie aplikacji lub nawet sprawi, że ta będzie nieużywalna.

W dobie RN / Fluttera oraz aplikacji progresywnych odradzałbym wchodzenia w aplikacje hybrydowe. Jeśli jednak nadal chcesz rozważyć to podejście, przeczytaj kolejny akapit, ponieważ aplikacje hybrydowe umiejscowiłbym dokładnie w tym samym miejscu, którym obecnie są aplikacje progresywne.

Progressive Web Application (PWA)

PWA to stosunkowo świeże podejście w świecie programowania. Po raz pierwszy pojawiło się w 2015 roku, a spopularyzowane zostało na przestrzeni ostatnich trzech lat. Jest to nic innego jak aplikacja webowa zbudowana zgodnie ze standardami PWA określonymi przez inżynierów Google'a. Aplikacje PWA bazują na możliwościach dzisiejszych przeglądarek i bardzo często działają w oparciu o natywne moduły, takie jak Bluetooth czy geolokalizacja. Zaleceniem jest, aby taka aplikacja była pisana w myśl mobile-first albo chociaż żeby wyglądem i działaniem przypominała aplikacje mobilne.

PWA nastawione jest na naśladowanie natywnego podejścia. Co więcej, aplikacje zgodne ze standardami PWA mogą zostać zainstalowane na dowolnym urządzeniu. Przybyło na ratunek, by wypełnić lukę pomiędzy aplikacjami natywnymi a stronami Internetowymi. Pewnie spotkaliście się ze stronami, które proponują Wam dodanie do ekranu domowego. To właśnie są PWA. Po zatwierdzeniu takiego komunikatu aplikacja PWA zostanie dodana do waszego telefonu, zupełnie jakby była zwykłą aplikacją mobilną. Ponadto, jeżeli pójdziemy krok dalej i z naszej PWA zrobimy TWA (Trusted Web Activity), to będziemy mogli ją wystawić w sklepie Play Store.

Aby spełnić wymagania dotyczące Progressive Web Application, warto posłużyć się narzędziem dostarczonym przez Google - Lighthouse. Narzędzie to pozwala zbadać dowolną stronę internetową pod kątem wydajności, dobrych praktyk, dostępności, SEO, czy właśnie zgodności ze standardami PWA.

Sercem PWA są Service Workery. Ich użycie daje wachlarz progresywnych możliwości. Od obsługi push notyfikacji, przez synchronizację danych w tle, aż po cache'owanie danych statycznych oraz dynamicznych. Wszystkie te dobrodziejstwa składają się na bardzo wysoki poziom UX'u. Przyjmując odpowiednie strategie cache'owania możemy zapewnić użytkownikom błyskawiczne ładowanie aplikacji (przechowując w pamięci podstawowe elementy potrzebne do jej wyświetlenia). Idąc krok dalej - załóżmy, że nasza aplikacja opiera się na komunikacji z serwerem. Otrzymane dane również możemy cache'ować. Taki zabieg pozwala zapewnić użytkownikom możliwości korzystania z aplikacji w trybie offline. Nawet sam skaczący dinozaur z Chrome się przy tym chowa ;). Więcej do poczytania o Service Workerach tutaj.

Podsumowując - progresywna aplikacja sieciowa świetnie sprawdzi się, gdy:

  • Nie potrzebujemy wykonywać złożonych obliczeń,
  • Poziom bezpieczeństwa równy aplikacjom sieciowym jest nam wystarczający,
  • Chcemy mieć nowoczesną stronę obsługującą natywne API, która posłuży również jako aplikacja mobilna.

Kilka popularnych przykładów będących PWA: Morele.net, Uber, Spotify.

Nowoczesne frameworki front-endowe znacznie ułatwiają budowanie aplikacji PWA. Mimo tego nie są niezbędne - praktycznie każdą aplikację webową jesteśmy w stanie zrobić progresywną.

Warto mieć na uwadze, że Apple jest niezbyt przychylne podejściu PWA i samo korzystanie z jego dobrodziejstw jest mocno ograniczone. Najprawdopodobniej spowodowane jest to polityką firmy, w którą PWA się nie wpisuje.

Podsumowanie

Planując zbudowanie aplikacji mobilnej, warto zweryfikować swoje potrzeby i dobrać do nich odpowiednie rozwiązanie. Nie zawsze opłaca się inwestować w aplikacje natywne. Lwia część potrzeb biznesowych może zostać rozwiązane dużo tańszym, bardziej uniwersalnym rozwiązaniem. Mam nadzieję, że dzisiejszy artykuł zapewni Wam podstawową wiedzę na temat obecnych możliwości w świecie mobile i podchodząc do tworzenia aplikacji mobilnej będziecie wiedzieć na czym stoicie.

Przydatne linki

Aplikacje natywne:

Aplikacje Hybrydowe:

Progressive Web Applications:

Do góry