Sprawdzone metody zachowywania stanu aplikacji za pomocą IndexedDB

Poznaj sprawdzone metody synchronizowania stanu aplikacji między IndexedDB a popularnymi bibliotekami zarządzania stanem.

Gdy użytkownik po raz pierwszy wczytuje witrynę lub aplikację, utworzenie początkowego stanu aplikacji, która posłuży do renderowania interfejsu, często wymaga sporo pracy. Czasami aplikacja musi np. uwierzytelnić się po stronie klienta, a potem wysłać kilka żądań do interfejsu API, zanim zbierze wszystkie dane, które musi wyświetlić na stronie.

Przechowywanie stanu aplikacji w IndexedDB może być świetnym sposobem na przyspieszenie wczytywania powtarzających się wizyt. Aplikacja może wtedy zsynchronizować się z dowolnymi usługami interfejsu API w tle i leniwie aktualizować interfejs użytkownika nowymi danymi, stosując strategię nieaktywnej w trakcie ponownej weryfikacji.

Jednak gdy używasz IndexedDB, musisz pamiętać o wielu ważnych kwestiach, które mogą nie być oczywiste dla programistów, którzy dopiero zaczynają korzystać z interfejsów API. W tym dokumencie znajdziesz odpowiedzi na najczęstsze pytania oraz informacje o najważniejszych kwestiach, o których należy pamiętać podczas zapisywania stanu aplikacji w IndexedDB.

Zadbaj o przewidywalność aplikacji

Wiele zawiłości związanych z IndexedDB wynika z faktu, że deweloper nie ma nad nimi kontroli. W tej sekcji omawiamy wiele problemów, o których należy pamiętać podczas pracy z bazą IndexedDB.

Zapisywanie w pamięci może się nie udać

Błędy podczas zapisywania danych w IndexedDB mogą występować z różnych powodów, a w niektórych przypadkach są one poza kontrolą dewelopera. Na przykład niektóre przeglądarki nie zezwalają na zapisywanie w IndexedDB w trybie przeglądania prywatnego. Możliwe też, że użytkownik korzysta z urządzenia, na którym prawie zabrakło miejsca na dysku, i przeglądarka nie pozwoli mu na zapisanie czegokolwiek.

Z tego powodu jest niezwykle ważne, aby zawsze wdrażać prawidłową obsługę błędów w kodzie IndexedDB. Oznacza to również, że dobrze jest zachować stan aplikacji w pamięci (oprócz jej przechowywania), dzięki czemu interfejs użytkownika działa w trybie przeglądania prywatnego lub gdy nie ma dostępnego miejsca na dane (nawet jeśli niektóre inne funkcje aplikacji wymagające pamięci masowej nie będą działać).

Przechowywane dane mogły zostać zmodyfikowane lub usunięte przez użytkownika.

W przeciwieństwie do baz danych po stronie serwera, w których można ograniczyć nieautoryzowany dostęp, bazy danych po stronie klienta są dostępne dla rozszerzeń przeglądarki i narzędzi dla programistów, a użytkownik może je wyczyścić.

Użytkownicy mogą rzadko zmieniać swoje dane przechowywane lokalnie, ale użytkownicy często je usuwają. Ważne jest, aby aplikacja poradziła sobie z obydwoma tymi przypadkami bez błędów.

Zapisane dane mogą być nieaktualne

Podobnie jak w przypadku poprzedniej sekcji, nawet jeśli użytkownik sam nie zmodyfikował danych, możliwe, że dane, które przechowuje w pamięci, zostały zapisane przez wcześniejszą wersję kodu, na przykład wersję z błędami.

IndexedDB ma wbudowane obsługiwanie wersji schematu i aktualizowania za pomocą metody IDBOpenDBRequest.onupgradeneeded(). Mimo to nadal musisz napisać kod aktualizacji w taki sposób, aby obsługiwał użytkowników korzystających z poprzedniej wersji (w tym z wersji zawierającej błąd).

Bardzo pomocne mogą być tu testy jednostkowe, ponieważ często nie ma możliwości ręcznego przetestowania wszystkich możliwych ścieżek i przypadków uaktualnienia.

Utrzymaj wydajność aplikacji

Jedną z głównych cech IndexedDB jest asynchroniczny interfejs API, ale pamiętaj, że podczas korzystania z niej nie musisz się martwić o wydajność. W wielu przypadkach nieprawidłowe użycie może nadal zablokować wątek główny, co może prowadzić do braku odpowiedzi.

Zasadniczo odczyty i zapisy w IndexedDB nie powinny być większe niż wymagane do danych, do których uzyskujesz dostęp.

IndexedDB umożliwia przechowywanie dużych, zagnieżdżonych obiektów jako pojedynczych rekordów (co jest dość wygodne z perspektywy programisty), ale nie należy tego robić. Dzieje się tak, ponieważ gdy IndexedDB przechowuje obiekt, musi najpierw utworzyć strukturalny klon tego obiektu, a proces tworzenia takiego klona odbywa się na głównym wątku. Im większy obiekt, tym dłuższy czas blokowania.

Stwarza to pewne problemy przy planowaniu sposobu zapisywania stanu aplikacji w IndexedDB, ponieważ większość popularnych bibliotek do zarządzania stanem (np. Redux) zarządza całym drzewem stanu jako pojedynczym obiektem JavaScript.

Ten sposób zarządzania stanem ma wiele zalet, a chociaż przechowywanie całego drzewa stanu jako jednego rekordu w IndexedDB może być kuszące i wygodne, wykonywanie tej czynności po każdej zmianie (nawet wtedy, gdy zostanie ograniczone/odrzucone) spowoduje niepotrzebne zablokowanie wątku głównego, ale zwiększy prawdopodobieństwo wystąpienia błędów, a w niektórych przypadkach spowoduje nawet wyłączenie karty przeglądarki.

Zamiast przechowywać całe drzewo stanów w jednym rekordzie, podziel je na poszczególne rekordy i aktualizuj tylko te, które się zmieniają.

Podobnie jak w przypadku większości sprawdzonych metod, nie jest to zasada „wszystko albo nic”. W przypadku, gdy nie można podzielić obiektu stanu i zapisać tylko minimalny zestaw zmian, podzielenie danych na poddrzewa i zapisanie tylko ich jest nadal lepsze niż ciągłe zapisywanie całego drzewa stanu. Drobne ulepszenia są lepsze niż brak ulepszeń.

Pamiętaj też, aby zawsze mierzyć wpływ na wydajność pisanego kodu. Chociaż w rzeczywistości małe zapisy w IndexedDB są skuteczniejsze niż duże zapisy, ma to znaczenie tylko wtedy, gdy zapisy do IndexedDB przez aplikację prowadzą do długich zadań, które blokują główny wątek i pogarszają komfort użytkowników. Ważne jest, aby wiedzieć, pod kątem czego prowadzisz optymalizację.

Podsumowanie

Deweloperzy mogą korzystać z mechanizmów przechowywania danych klientów, takich jak IndexedDB, aby poprawić wrażenia użytkowników korzystających z aplikacji, nie tylko dzięki zachowywaniu stanu między sesjami, ale także skróceniu czasu potrzebnego na wczytanie stanu początkowego przy wielokrotnych wizytach.

Chociaż prawidłowe korzystanie z IndexedDB może znacznie poprawić komfort użytkowników, nieprawidłowe korzystanie z tego interfejsu lub brak obsługi błędów może prowadzić do problemów z aplikacją i niezadowolenia użytkowników.

Ponieważ pamięć klienta zależy od wielu czynników, na które nie masz wpływu, ważne jest, aby Twój kod był dobrze przetestowany i odpowiednio reagował na błędy, nawet te, które na pierwszy rzut oka wydają się mało prawdopodobne.