Tryb offline aplikacji webowej: praca w terenie bez zasięgu

Aplikacja webowa może działać także tam, gdzie nie ma zasięgu – w piwnicy, na budowie, w magazynie czy na wsi. Warunkiem jest zaprojektowanie trybu offline jako części procesu pracy, a nie dodatku dokładanego tuż przed uruchomieniem. Technicznie tworzą go service worker, który zapisuje aplikację na urządzeniu, lokalna baza danych w przeglądarce dla rozpoczętych rekordów oraz kolejka wychodzących zmian, którą aplikacja po powrocie połączenia wysyła na serwer.

O sukcesie decydują jednak zasady: jakie dane pracownik w terenie ma przy sobie, co może zrobić bez serwera, jak długo niewysłane rekordy mogą pozostawać w telefonie i co się stanie, gdy ten sam rekord w międzyczasie zmieni biuro. Artykuł jest przeznaczony dla właścicieli i menedżerów firm, którzy planują aplikację dla serwisantów, oględzin, inwentaryzacji lub przeglądów i zastanawiają się, jak powinien wyglądać tryb offline aplikacji webowej.

Przykład: przeglądy kotłów w piwnicach bez zasięgu

Przykład ilustracyjny, firma jest fikcyjna. Firma serwisowa wykonuje przeglądy kotłów gazowych, często w kotłowniach i piwnicach bez zasięgu sieci komórkowej. Technik zapisuje dziś ustalenia na papierze, wieczorem przepisuje je do systemu, a zdjęcia wysyła przez prywatny komunikator.

Stan docelowy: rano, w firmowej sieci Wi-Fi, aplikacja pobiera plan dnia, adresy, historię urządzeń i formularze protokołów. Na miejscu technik wypełnia protokół, dołącza zdjęcia, a klient podpisuje się na ekranie. Rekord zapisuje się w telefonie ze statusem „Czeka na wysłanie”. Gdy zasięg wraca, aplikacja go wysyła, serwer potwierdza odbiór, a status zmienia się na „Wysłano”. Jeśli biuro w międzyczasie anulowało zlecenie, technik widzi konflikt do rozwiązania, a nie ciche nadpisanie swojej pracy.

Co tryb offline musi obsłużyć, a czego nie

Pierwsza decyzja nie jest techniczna. Dla każdego zadania ustalcie, czy wykonuje się je całkowicie offline, jako wersję roboczą, którą potwierdzi serwer, czy tylko online. Wszystko, co wymaga jednego wiarygodnego stanu – numeracja faktur, magazyn, ceny – zostawcie na serwerze.

Zadanie Offline Dlaczego
Wyświetlenie planu dnia i historii urządzenia Tak, z danych pobranych wcześniej Technik potrzebuje kontekstu także bez zasięgu
Wypełnienie protokołu, dołączenie zdjęć i podpisu Tak, zapis lokalny i wysyłka później Główny powód wprowadzenia trybu offline
Założenie nowego zlecenia na miejscu Tak, jako wersja robocza z tymczasowym identyfikatorem Numer zlecenia nadaje dopiero serwer
Wystawienie faktury lub rezerwacja towaru Nie, tylko przygotowanie danych Numerację i stan magazynu kontroluje serwer
Zmiana cennika lub uprawnień Nie Te dane powinny mieć jedno źródło prawdy

Każde „tak” w tabeli oznacza dodatkowe prace programistyczne i testy. Do trybu offline powinny więc trafić tylko zadania, które naprawdę wykonuje się bez zasięgu.

Techniczne elementy składowe i ich ograniczenia

Service worker i zapisana aplikacja

Service worker to skrypt działający w osobnym wątku. Podczas instalacji może zapisać strony, style, skrypty i obrazy aplikacji w lokalnej pamięci podręcznej (cache), a następnie przechwytywać jej żądania – najpierw z cache albo najpierw z sieci, z cache jako zapasem. Według przewodnika MDN po pracy offline i w tle właściwa strategia zależy od konkretnej aplikacji. W aplikacji terenowej zalecamy, aby sam interfejs aplikacji był serwowany z cache z jasnym wersjonowaniem, a dane zleceń przechowywane w lokalnej bazie danych, którą aplikacja aktualizuje z serwera przy każdym połączeniu.

Lokalna baza danych: IndexedDB, a nie localStorage

localStorage przechowuje wyłącznie tekstowe pary klucz–wartość i według dokumentacji MDN o limitach pamięci jest ograniczony do 5 MiB na jedno źródło (origin). Na zdjęcia i kolejkę zmian to za mało. Do większych danych strukturalnych służy IndexedDB, a do plików prywatny system plików źródła (OPFS).

Limity i usuwanie danych

Dane są domyślnie zapisywane w trybie „best-effort”, czyli bez gwarancji trwałości: pozostają, dopóki źródło nie przekroczy limitu, na urządzeniu jest miejsce, a użytkownik ich nie usunie. Gdy brakuje miejsca, przeglądarka usuwa dane najdawniej używanych źródeł – zawsze wszystkie dane źródła naraz, nigdy tylko ich część (MDN).

Limity są wysokie, ale nie stanowią gwarancji. Przeglądarki oparte na Chromium pozwalają źródłu zająć do 60% całkowitej pojemności dysku, Firefox w trybie best-effort mniejszą z wartości: 10% dysku lub 10 GiB, a Safari od wersji 17 około 60% dysku (MDN). Liczy się jednak całkowita pojemność, a nie wolne miejsce, a według wpisu na blogu WebKit o zasadach przechowywania danych chodzi o górną granicę bez gwarancji. Aplikacja musi więc obsłużyć błąd QuotaExceededError.

Safari przy włączonej ochronie przed śledzeniem między witrynami dodatkowo usuwa dane utworzone przez skrypt, jeśli użytkownik nie wchodził w interakcję z witryną w ciągu ostatnich siedmiu dni korzystania z przeglądarki. Przed usunięciem przy braku miejsca chroni trwała pamięć (persistent storage), o którą aplikacja prosi przez navigator.storage.persist(). Firefox pyta użytkownika, Safari i większość przeglądarek opartych na Chromium decydują automatycznie na podstawie historii interakcji, a WebKit bierze pod uwagę także to, czy witryna jest uruchamiana z ekranu początkowego. Według badań zespołu Chrome, na które powołuje się MDN, przeglądarki bardzo rzadko usuwają dane regularnie odwiedzanych witryn. Mimo to traktujcie telefon jako tymczasowy bufor, a nie miejsce, w którym mają pozostać dane firmy.

Stan połączenia i synchronizacja w tle

Właściwość navigator.onLine nie jest wiarygodna: połączenie z siecią lokalną zwykle uznaje się za online, nawet jeśli ta sieć nie ma dostępu do internetu. MDN zaleca więc, aby na jej podstawie nie wyłączać funkcji, a jedynie sygnalizować, że użytkownik może być offline. Za wysłany uznawajcie tylko rekord, którego odbiór potwierdził serwer.

Background Synchronization API pozwala odłożyć wysyłkę i przekazać ją service workerowi do czasu, aż połączenie będzie stabilne. MDN oznacza je jednak jako funkcję o ograniczonej dostępności, a działa ono wyłącznie w bezpiecznym kontekście (HTTPS). Żądanie można zarejestrować tylko przy otwartej aplikacji, przeglądarka może ponowić próbę tylko ograniczoną liczbę razy, a zbyt długą operację przerywa, przy czym kolejna próba zaczyna się od początku (MDN). Synchronizacja w tle jest więc dodatkiem. Podstawą powinna być wysyłka przy otwarciu aplikacji, po przywróceniu połączenia i przyciskiem „Wyślij teraz”, w małych partiach, które można bezpiecznie powtórzyć.

Wdrożenie w siedmiu krokach

  1. Zmapujcie pracę w terenie. Ustalcie, gdzie i jak długo ludzie nie mają zasięgu, jakich urządzeń używają (firmowych czy prywatnych, iPhone czy Android) i ile rekordów oraz zdjęć powstaje dziennie.
  2. Określcie zakres offline. Dla każdego zadania zdecydujcie według tabeli: całkowicie offline, wersja robocza do potwierdzenia lub tylko online.
  3. Przygotujcie model danych. Każdy rekord otrzymuje już na urządzeniu unikalny identyfikator (na przykład UUID), wersję i status synchronizacji. Serwer musi rozpoznać ponowne przesłanie i nie utworzyć duplikatu.
  4. Zbudujcie kolejkę wychodzącą. Zmiana jest najpierw zapisywana w lokalnej bazie danych i w kolejce, a dopiero potem wysyłana – w kolejności powstania, partiami i z ponawianiem. Zdjęcia są przesyłane dopiero wtedy, gdy serwer przyjął sam rekord.
  5. Zadbajcie o pamięć. Poproście o trwałą pamięć, monitorujcie szacowane wykorzystanie przez navigator.storage.estimate(), przed zapisaniem zmniejszajcie zdjęcia do rozdzielczości, której proces naprawdę potrzebuje, i po potwierdzeniu przez serwer usuwajcie lokalne kopie.
  6. Pokazujcie status synchronizacji. Przy każdym rekordzie powinno być widać, czy czeka na wysłanie, został wysłany, czy ma konflikt. Przed wylogowaniem aplikacja musi ostrzec, a wygaśnięcie logowania nie może zatrzymać pracy ani usunąć kolejki.
  7. Testujcie w realnych warunkach. Sprawdźcie tryb samolotowy, Wi-Fi bez internetu, zamknięcie aplikacji podczas wysyłania, pełną pamięć i wdrożenie nowej wersji z niewysłanymi danymi – na iPhonie i na Androidzie.

Konflikty: kto wygrywa, gdy rekord zmienił się w dwóch miejscach

Konflikt powstaje, gdy technik edytuje rekord offline, a ktoś inny w międzyczasie zmienia go na serwerze. Zasadę „ostatni zapis wygrywa” najłatwiej zaprogramować, ale po cichu odrzuca ona pracę jednej z osób. Dlatego zasady ustalcie z góry, według typu danych.

Sytuacja Zalecana zasada Kompromis
Technik uzupełnia protokół, biuro poprawia dane kontaktowe klienta Scalanie według pól, każde pole ma swojego właściciela Własność pól trzeba precyzyjnie określić
Biuro anulowało zlecenie, technik w międzyczasie je wykonał Nie nadpisywać, oznaczyć konflikt do decyzji dyspozytora Ktoś musi regularnie rozwiązywać konflikty
Dwóch techników edytowało ten sam rekord Przyjąć zmianę do aktualnej wersji, drugą zwrócić jako konflikt Drugi technik musi sprawdzić swoją zmianę
Zdjęcia, notatki i podpisy Tylko dodawać, nigdy nie nadpisywać Więcej przechowywanych danych, ale nic nie ginie
Cenniki i słowniki Serwer jest jedynym źródłem, urządzenie tylko je odczytuje Offline na urządzeniu może być starsza wersja

W razie konfliktu zachowajcie obie wersje wraz z autorem i czasem. W przeciwnym razie sporu o to, co technik naprawdę zapisał na miejscu, nie da się później rozstrzygnąć.

Aplikacja webowa (PWA) czy aplikacja natywna?

Aplikacja webowa ma jeden kod dla wszystkich urządzeń, rozpowszechnia się ją za pomocą linku, a nową wersję wdrażacie na serwer bez sklepów z aplikacjami. Akceptujecie jednak zasady przeglądarki: pamięć w trybie best-effort, jeśli przeglądarka nie przyzna trybu trwałego, ograniczoną synchronizację w tle i service workera, którego przeglądarka zatrzymuje, gdy uzna to za stosowne. Aplikacja natywna może przechowywać dane we własnej pamięci poza przeglądarką, więc te limity i zasady usuwania danych jej nie dotyczą. Oznacza jednak rozwój na iOS i Androida oraz dystrybucję przez sklepy z aplikacjami lub przez system zarządzania urządzeniami firmowymi.

  • Aplikacja webowa zwykle wystarcza, jeśli chodzi o formularze, listy kontrolne, zdjęcia i podpisy, a urządzenia łączą się z siecią przynajmniej raz dziennie.
  • Aplikację natywną rozważcie, jeśli ludzie pracują bez połączenia całymi dniami, potrzebują na urządzeniu dużych ilości danych, na przykład map czy filmów, lub dane muszą być wysyłane w tle bez otwierania aplikacji.

Zdecydujcie przed rozpoczęciem prac. Zmiana podejścia w połowie projektu oznacza przebudowę przechowywania danych i synchronizacji, czyli samego rdzenia trybu offline.

Częste błędy

  • Tryb offline dopiero po uruchomieniu. Model danych bez lokalnych identyfikatorów i wersji trudno później przebudować.
  • Poleganie na navigator.onLine. Wi-Fi bez internetu wygląda jak połączenie, a rekordy utykają.
  • Dane w localStorage. Tylko tekst i mała pojemność – nie nadaje się na zdjęcia i kolejkę.
  • Telefon jako jedyna kopia. Niewysłane rekordy leżą na urządzeniu całymi dniami, choć przeglądarka może usunąć wszystkie dane witryny naraz.
  • Niewidoczny status synchronizacji. Technik nie wie, co zostało wysłane, i wylogowuje się lub czyści dane przeglądarki.
  • Nowa wersja bez migracji. Aktualizacja nie potrafi odczytać niewysłanej kolejki albo ją usuwa.
  • Przeglądanie prywatne. Dane są zwykle usuwane po zakończeniu sesji prywatnej, więc nie używajcie go do pracy w terenie.

Lista kontrolna przed wdrożeniem

  • Tabela zadań (offline, wersja robocza, tylko online) jest zatwierdzona przez zespół terenowy i biuro.
  • Każdy rekord ma lokalny unikalny identyfikator, wersję i status synchronizacji.
  • Serwer rozpoznaje ponowne przesłanie i nie tworzy duplikatu.
  • Rekordy i zdjęcia są w IndexedDB lub OPFS, a nie w localStorage.
  • Aplikacja prosi o trwałą pamięć, monitoruje jej wykorzystanie i radzi sobie z pełną pamięcią.
  • Powodzenie wysyłki potwierdza serwer, a nie stan połączenia w przeglądarce.
  • Synchronizacja działa także bez Background Synchronization API.
  • Zasady konfliktów są spisane i przetestowane, a ktoś odpowiada za rozwiązywanie konfliktów.
  • Ani wylogowanie, ani wygaśnięcie logowania nie usuwa niewysłanych danych bez ostrzeżenia.
  • Na urządzeniach są tylko dane potrzebne do bieżących zleceń, a telefony mają blokadę ekranu.

Najczęściej zadawane pytania

Czy aplikacja webowa offline działa także na iPhonie?

Tak. Safari od wersji 17 w pełni obsługuje Storage API, a aplikacja webowa dodana do ekranu początkowego ma takie same limity jak w przeglądarce. WebKit przy prośbie o trwałą pamięć bierze pod uwagę, czy witryna jest otwarta jako aplikacja z ekranu początkowego (WebKit). Dlatego zalecamy dodanie aplikacji do ekranu początkowego i synchronizację przynajmniej raz dziennie. W UE na iOS od wersji 17.4 mogą działać także przeglądarki z innym silnikiem, które stosują własne zasady przechowywania danych (MDN).

Ile danych aplikacja może zapisać w telefonie?

Zależy to od przeglądarki i urządzenia. Górne granice są wysokie, ale liczone od całkowitej pojemności dysku, a nie od wolnego miejsca, więc rzeczywistym ograniczeniem może być zapełniony telefon. Aplikacja powinna monitorować szacowane wykorzystanie, zmniejszać zdjęcia i po potwierdzeniu przez serwer usuwać lokalne kopie.

Co się stanie, gdy technik zamknie aplikację przed wysłaniem?

Rekordy zapisane w IndexedDB pozostaną na urządzeniu, a aplikacja wyśle je przy następnym otwarciu. Jeśli przeglądarka obsługuje Background Synchronization API, a żądanie zarejestrowano przy otwartej aplikacji, może je wysłać także po jej zamknięciu. Funkcja nie jest jednak dostępna wszędzie, a przeglądarka ogranicza liczbę i czas trwania prób, dlatego technik powinien zawsze widzieć, co jeszcze czeka na wysłanie.

Czy z powodu trybu offline potrzebujemy aplikacji natywnej?

Przy formularzach, zdjęciach i podpisach z codzienną synchronizacją zwykle nie. Aplikację natywną rozważcie przy całych dniach bez połączenia, dużych ilościach danych na urządzeniu lub konieczności wysyłania danych w tle. Zdecydujcie jeszcze przed rozpoczęciem prac.

Jak zacząć

Jeśli chcecie, aby wasi pracownicy w terenie przestali przepisywać papiery i wysyłać zdjęcia przez komunikator, zacznijcie od tabeli zadań i jednego prawdziwego dnia pracy w terenie. Zobaczcie, jak tworzymy aplikacje webowe na zamówienie, lub napiszcie do nas przez stronę kontaktową. Pomożemy wam określić zakres offline, zaprojektować synchronizację i zasady konfliktów oraz przetestować aplikację w warunkach, w których będziecie z niej korzystać. Jeśli protokoły mają trafiać dalej do systemu ERP lub CRM, przygotujemy także integrację API. Więcej praktycznych poradników znajdziecie na naszym blogu.

Źródła

Proszę wybrać, na które pliki cookie Państwo zezwalają. Wybór można w każdej chwili zmienić za pomocą linku w stopce lub przycisku cookies.

Ochrona prywatności i szczegóły dotyczące plików cookie