Tworzenie aplikacji PWA z wykorzystaniem Angular 6

Od jakiegoś czasu widzimy w branży duże zainteresowanie Progressive Web Application (PWA).

Coraz więcej firm buduje aplikacje wykorzystujące tę koncepcję. Powstają katalogi (np. PWA Stats), w których można znaleźć informacje o przypadkach użycia i pozytywnych skutkach (polepszeniu konwersji, zwiększeniu ilość podstron odwiedzonych w sesji czy też zwiększeniu czasu spędzonego na stronie). Giganci rynku, tacy jak Microsoft również promują tę technologię pozwalając dodawać aplikacje PWA do sklepu Windows Store.

Czym charakteryzują się takie aplikacje i jakie są ich zalety oraz wady, opisaliśmy na naszym blogu jakiś czas temu. Zainteresowanych spojrzeniem “z lotu ptaka” odsyłam do tego artykułu.

Dlaczego my, jako firma, również zainteresowaliśmy się tym tematem? Myślę, że zamiast pisać rozprawkę, wystarczy pokazać wykresy z badań przeprowadzonych w 2017 roku.

 

PWA Angular SmartphoneIle aplikacji użytkownicy smartfonów pobierają ze sklepów przez miesiąc.

 

 

Smartphone App RankIle czasu użytkownicy smartfonów spędzają w najpopularniejszych aplikacjach.

 

Analizując powyższe wykresy możemy wyciągnąć następujące wnioski:

  • po zainstalowaniu kilku najpotrzebniejszych aplikacji użytkownicy nie ściągają nic nowego;
  • ponad 95% czasu użytkownicy spędzają w 10 najpopularniejszych aplikacjach. Długo nie myśląc można wymienić: Facebook, Messenger, Youtube, Google Chrome, Gmail, Instagram, WhatsApp, Spotify. Gdzie tutaj jest miejsce na naszą, nową aplikację?
  • niechęć do pobierania nowych aplikacji można zinterpretować dwojako: większość osób korzysta ze smartfona do przewijania Facebooka lub aktualny proces instalacji aplikacji poprzez sklepy jest zbyt skomplikowany i praktycznie nikomu nie chce się tego robić. Osobiście jestem zwolennikiem drugiej interpretacji i dlatego też uważam, że PWA to szansa na zmianę tych nawyków;

W tym poście chciałbym skupić się na aspektach technicznych tworzenia aplikacji PWA z wykorzystaniem Angulara 6. Dla przypomnienia – szóstka to najnowsza dostępna wersja na tę chwilę 😉

 

Angular PWA z użyciem Angular CLI

Krótko i na temat:

Angular CLI

To tyle. W tym momencie mamy już szkielet aplikacji wykorzystującej koncepcje PWA.

Co tak naprawdę tutaj zrobiliśmy?

W pierwszym kroku zainstalowaliśmy sobie Angular CLI za pomocą yarn’a (równie dobrze można użyć npm’a, ale aktualnie to yarn jest przecież super fancy).

Za pomocą zainstalowanego Angular CLI stworzyliśmy szkielet nowej aplikacji o nazwie pwa-example. Flaga –service-worker automatycznie załatwiła nam kilka spraw związanych z konfiguracją mechanizmu service worker’ów (dokładniej o tym w dalszej części artykułu). W trzecim kroku przeszliśmy do stworzonego folderu i dodaliśmy paczkę @angular/pwa.

Wszystko to, co zrobiło za nas CLI możemy również zrobić ręcznie. Tylko po co?

Robić ręcznie nie musimy, ale na pewno powinniśmy zrozumieć, co się stało pod spodem i jak wygląda stworzona konfiguracja.

 

Co się stało – package.json

Kodowanie PWA Angular

W pliku package.json dodane zostały zależności do niezbędnych paczek.

 

Co się stało – angular.json

Kodowanie PWA Angular

W pliku angular.json do sekcji związanej z konfiguracją dodany został wpis włączający service workery.

 

Co się stało – Service Workers

Kilka razy w tym artykule użyte zostało sformułowanie Service Workers, jednak samo pojęcie nie zostało jeszcze wyjaśnione.

Service Workers rozszerzają mechanizm Web Workers, który pozwala na uruchamianie skryptów w tle, w wątku oddzielonym od głównego wątku przeglądarki. Service Workers używane są jako swego rodzaju proxy między aplikacją kliencką, a aplikacją serwerową. Możemy dzięki nim cache’ować zasoby statyczne lub wywołania konkretnego API (np. zapytanie o listę zakupów zapisaną na serwerze może być pobrane z SW, jeśli aktualnie nie mamy dostępu do internetu). Dodatkowo, dają wsparcie do takich mechanizmów jak push notifications oraz background sync.

PWA z Angular 6Mechanizm działania Service Worker’a jako interceptora request’u z aplikacji.

Pisząc o tym temacie, należy jeszcze wspomnieć o kilku ważnych informacjach:

  • Service Workery zostały stworzone tak, aby były w pełni asynchroniczne, dlatego też synchroniczne zapytania oraz mechanizm localStorage nie powinien być używany razem z nimi.
  • Service Workery nie mają dostępu bezpośrednio do drzewa DOM. Do komunikacji z aplikacją należy używać dedykowanych metod.
  • Nie powinniśmy używać Service Worker’ów jako czegoś, gdzie zapisujemy globalny stan między konkretnymi zdarzeniami. Jeśli potrzebny jest taki mechanizm – IndexedDB.
  • Service Workery nie są powiązane ze standardowym mechanizmem Cache-Control przeglądarki

Aktualnie wszystkie najpopularniejsze przeglądarki wspierają ten mechanizm. Jeśli temat wydaje się interesujący, polecam się zapoznać z Web Workers API oraz Service Workers API. Dodatkowo warto spojrzeć również na świetny artykuł Jake’a Archibalda na temat mechanizmów cache’owania i tematów z tym związanych – Offline Cookbook.

 

Co się stało – ngsw-config.json

ngsw-config.json to plik, w którym możemy konfigurować zachowania dotyczące cache’owania poszczególnych zasobów w aplikacji.

Kod PWA Angular

Co możemy wyczytać z powyższej konfiguracji? W sekcji assetGroups mamy dwa obiekty, gdzie w pierwszym konfigurujemy cache’owanie głównego pliku index.html oraz wszystkich plików JS oraz CSS, drugi dotyczy cache’owania lokalnych zasobów z folderu assets.

Wpisy różnią się ustawieniem opcji installMode oraz updateMode. Oficjalna dokumentacja Angulara bardzo dobrze tłumaczy, czym różnią się poszczególne tryby.

Warto tutaj dodać, że do cache’owania wywołań API używa się sekcji dataGroups. Przykładową konfigurację użytą w naszym projekcie zamieszczam poniżej:

Kodowanie PWA Angular6

 

Co się stało – app.module.ts

PWA / Angular 6

W app.module.ts, który jest tzw. root module naszej aplikacji dodany został ServiceWorkerModule. Moduł ten daje możliwość wstrzykiwania nam serwisów SwUpdate (pozwala zarządzać aktualizacją naszej aplikacji, np. poinformować użytkownika o nowej wersji) oraz SwPush (związany z push notifications) oraz rejestruje Angular Service Worker’a w przeglądarce. Parametrem enabled możemy sterować, kiedy SW mają zostać zarejestrowane. W powyższym kodzie opieramy się na zmiennej production z pliku environment, która określa czy aplikacja uruchamiana jest w środowisku produkcyjnym. Więcej tutaj.

 

Co się stało – podsumowanie

To tyle, jeżeli chodzi o zrozumienie co stało się po wpisaniu tych kilku komend. Wyjaśnienie nie kończy się na dwóch zdaniach, dlatego ważne jest poznanie tej autokonfiguracji od środka.

 

Angular PWA – jak to uruchomić?

Bardzo ważne – ng serve czyli standardowa komenda do uruchamiania aplikacji Angularowych podczas developmentu nie wspiera Service Workerów przez co nie jesteśmy w stanie przetestować działania aplikacji PWA.

Niezbędny jest mały serwer, na którym zostanie to uruchomione.

PWA Angular 6 kod

W pierwszej linii instalujemy paczkę z malutkim serwerem, na którym będzie hostowana nasza aplikacja. Następna komenda buduje naszą aplikację jako wersję produkcyjną. Następnie uruchamiamy serwer z wyłączonym cache’owaniem (flaga -c-1) wskazując folder, w którym mieści się zbudowana wersja aplikacji.

Jeśli wszystko poszło dobrze, możemy wejść pod adres http://localhost:8080 i sprawdzić czy Service Worker zarejestrował się poprawnie. U mnie wygląda to tak:

lokal host

 

Dodaj do ekranu startowego, czyli one-click install

Aplikacja działa, teraz możemy zająć się dodaniem funkcjonalności Dodaj do ekranu startowego. Dzięki temu będziemy mogli przypinać aplikacje PWA do ekranu głównego naszego smartfona. Należy pamiętać, że ta funkcjonalność dotyczy przeglądarek mobilnych, nie przez przypadek nazywa się Dodaj do ekranu startowego, a nie Dodaj do pulpitu.

Dodanie tej funkcjonalności składa się z dwóch kroków.

 

Dodanie pliku manifest.json do projektu

programowanie

Jest to tzw. Web App Manifest, w którym możemy wprowadzić podstawowe informacje o aplikacji. Nie będę tutaj zagłębiał się w konfiguracje poszczególnych pól, wszystko jest dobrze opisane w dokumentacji podlinkowanej w powyższym zdaniu.

 

Dodanie pliku manifest.json do angular.json oraz index.html

W pliku angular.json musimy dodać plik manifest.json do sekcji assets.

manifest json

W pliku index.html w sekcji head musimy dodać link do stworzonego pliku.

index.html

Należy również pamiętać, że ta funkcjonalność działa tylko i wyłącznie z aplikacjami, które serwowane są przez HTTPS.

 

Informowanie użytkownika o nowej wersji

W aplikacjach natywnych informowanie o nowej wersji odbywa się przez funkcjonalności sklepów. Trzeba ściągnąć nową wersję aplikacji, a ona zainstaluje się w tle. W aplikacjach PWA, aby otrzymać nową wersję aplikacji wystarczy odświeżyć stronę!

Jeśli chcemy, aby użytkownik był o takiej sytuacji poinformowany, wystarczy dodać kilka linijek kodu:

PWA aplikacje

Skutkuje to wyświetleniem użytkownikowi takiego komunikatu:

gif

 

Przykładowa aplikacja

Przykładowa aplikacja to Claim Register – bardzo uproszczona wersja aplikacji do rejestracji szkód przeznaczona dla ubezpieczonego.  Cały kod dostępny jest na GitHubie.

Zawiera bardzo uproszczony formularz rejestracji szkody oraz listę szkód. Podstawowe założenia/funkcjonalności:

  • Aplikacja łączy się z bezpłatnym API do pobierania informacji o markach samochodów. Zapytania do API są cache’owane, aby można było wybrać markę auta bez dostępu do internetu.
  • Wszystko, co wpisujemy w polach formularza zapisuje się w cache.
  • Lista szkód (My claims) nie jest cache’owana celowo, aby pokazać różnice w działaniu.
  • Do aplikacji można dodawać zdjęcia, które również zapisywane są w cache, dzięki czemu możemy dodawać zdjęcia nawet bez dostępu do internetu, a jak ten dostęp wróci, kliknąć przycisk Save i wysłać wszystko na serwer.
  • Na ekranie rejestracji nowej szkody są dostępne przyciski Enable notifications oraz Send notification, które służą do testowania funkcjonalności związanych z notyfikacjami.
  • Oprócz aplikacji klienckiej (claim-reporter-app)  w repozytorium dodana jest aplikacja claim-reporter-server – jest to prosty backend napisany w Node.js, który pozwala zapisać szkodę w bazie in-memory, dodać subskrybenta notyfikacji (osobę, do której notyfikacje będą mogły być wysyłane) oraz wysyłać notyfikacje.

Wygląda, że aplikacja jest napisana poprawnie patrząc na nią pod kątem “czy na pewno jest to PWA”. Sprawdzona została narzędziem Lighthouse od Google.

PWA Angular web appRaport z Lighthouse dotyczący przykładowej aplikacji ClaimRegister.

 

Podsumowując

Powinniśmy pamiętać, że sam pomysł oraz mechanizmy, które teraz używane są przez PWA, nie są najnowszym odkryciem zmieniającym świat.
Przed erą Service Workerów, już w 2010 roku dostępny był mechanizm Application Cache (AppCache). W materiałach archiwalnych Mozilli możemy znaleźć informacje o standardzie Open Web Apps. W 2012 W3C wydało rekomendacje Packaged Web Apps (Widgets). Także podobne koncepcje istnieją od lat.

Jednak trzeba przyznać, że aktualnie użytkownicy, urządzenia i przeglądarki mobilne są po prostu gotowe na PWA. Mocne wsparcie i promowanie tej technologii przez Google również ma tutaj bardzo duże znaczenie.

W artykule przeszliśmy przez proces budowania szkieletu aplikacji PWA z wykorzystaniem Angular 6. Framework ten ma bardzo dobre wsparcie tej koncepcji. Jego główni konkurenci, czyli React i Vue również świetnie sobie z tym radzą. Co ciekawe, od jakiegoś czasu wszystkie aplikacje React’a standardowo są Progressive Web App.

Zachęcam do zapoznania się z naszym repozytorium na GitHubie i tworzenia nowych aplikacji jako PWA 🙂

Autor: Robert Witkowski, ASC LAB