Sprawdzone metody zachowywania stanu aplikacji za pomocą IndexedDB

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

Gdy użytkownik po raz pierwszy wczytuje witrynę lub aplikację, często trzeba wykonać sporo pracy, aby utworzyć początkowy stan aplikacji, który jest używany do renderowania interfejsu. Na przykład czasami aplikacja musi uwierzytelnić użytkownika po stronie klienta, a następnie wysłać kilka żądań do interfejsu API, zanim uzyska wszystkie dane, które musi wyświetlić na stronie.

Przechowywanie stanu aplikacji w IndexedDB może być świetnym sposobem na przyspieszenie czasu wczytywania przy kolejnych wizytach. Aplikacja może następnie synchronizować się z dowolnymi usługami interfejsu API w tle i aktualizować interfejs użytkownika o nowe dane, stosując strategię stale-while-revalidate.

Jednak podczas korzystania z IndexedDB należy wziąć pod uwagę wiele ważnych kwestii, które mogą nie być od razu oczywiste dla deweloperów, którzy dopiero zaczynają korzystać z tych interfejsów API. W tym dokumencie znajdziesz odpowiedzi na najczęstsze pytania i omówienie najważniejszych kwestii, o których należy pamiętać podczas utrwalania stanu aplikacji w IndexedDB.

Zadbaj o przewidywalność aplikacji

Wiele złożonych kwestii związanych z IndexedDB wynika z faktu, że istnieje tak wiele czynników, nad którymi Ty (jako deweloper) nie masz kontroli. W tej sekcji omówiono wiele kwestii, o których należy pamiętać podczas pracy z IndexedDB.

Zapisy w pamięci masowej mogą się nie powieść

Błędy podczas zapisywania w IndexedDB mogą wystąpić 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że się też zdarzyć, że użytkownik korzysta z urządzenia, na którym prawie nie ma miejsca na dysku, a przeglądarka uniemożliwi zapisywanie jakichkolwiek danych.

Dlatego tak ważne jest, aby zawsze implementować prawidłową obsługę błędów w kodzie IndexedDB. Oznacza to również, że ogólnie warto przechowywać stan aplikacji w pamięci (oprócz zapisywania go), aby interfejs nie ulegał awarii podczas działania w trybie przeglądania prywatnego lub gdy miejsce na dane jest niedostępne (nawet jeśli niektóre inne funkcje aplikacji wymagające miejsca na dane 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 rzadko modyfikują dane przechowywane lokalnie, ale często je usuwają. Ważne jest, aby aplikacja mogła obsłużyć oba te przypadki bez błędów.

Przechowywane dane mogą być nieaktualne

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

IndexedDB ma wbudowaną obsługę wersji schematu i uaktualniania za pomocą metody IDBOpenDBRequest.onupgradeneeded(). Nadal jednak musisz napisać kod uaktualnienia w taki sposób, aby mógł obsłużyć użytkownika korzystającego z poprzedniej wersji (w tym wersji z błędem).

Bardzo pomocne mogą być testy jednostkowe, ponieważ często nie da się ręcznie przetestować wszystkich możliwych ścieżek i przypadków uaktualnienia.

Utrzymywanie wydajności aplikacji

Jedną z kluczowych funkcji IndexedDB jest asynchroniczny interfejs API, ale nie daj się zwieść, że nie musisz się martwić o wydajność podczas korzystania z niego. Istnieje wiele przypadków, w których nieprawidłowe użycie może nadal blokować wątek główny, co może prowadzić do braku odpowiedzi.

Ogólnie rzecz biorąc, odczyty i zapisy w IndexedDB nie powinny być większe niż jest to wymagane w przypadku danych, do których uzyskuje się dostęp.

IndexedDB umożliwia przechowywanie dużych, zagnieżdżonych obiektów jako pojedynczych rekordów (co jest bardzo wygodne z perspektywy dewelopera), ale należy unikać tej praktyki. Dzieje się tak, ponieważ gdy IndexedDB przechowuje obiekt, musi najpierw utworzyć jego uporządkowany klon, a proces klonowania uporządkowanego odbywa się w głównym wątku. Im większy obiekt, tym dłuższy czas blokowania.

Powoduje to pewne problemy podczas planowania sposobu utrwalania stanu aplikacji w IndexedDB, ponieważ większość popularnych bibliotek do zarządzania stanem (takich jak Redux) działa przez zarządzanie całym drzewem stanu jako pojedynczym obiektem w JavaScripcie.

Zarządzanie stanem w ten sposób ma wiele zalet, a przechowywanie całego drzewa stanu jako pojedynczego rekordu w IndexedDB może być kuszące i wygodne, ale robienie tego po każdej zmianie (nawet jeśli jest ograniczona lub opóźniona) spowoduje niepotrzebne blokowanie głównego wątku, zwiększy prawdopodobieństwo błędów zapisu, a w niektórych przypadkach może nawet spowodować awarię karty przeglądarki lub jej brak reakcji.

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

Podobnie jak w przypadku większości sprawdzonych metod, nie jest to zasada, którą trzeba stosować bezwzględnie. W przypadkach, gdy nie jest możliwe podzielenie obiektu stanu i zapisanie tylko minimalnego zestawu zmian, podzielenie danych na poddrzewa i zapisywanie tylko tych poddrzew jest nadal lepszym rozwiązaniem niż zapisywanie całego drzewa stanu. Niewielkie ulepszenia są lepsze niż żadne.

Na koniec: zawsze należy mierzyć wpływ napisanego kodu na wydajność. To prawda, że małe zapisy w IndexedDB będą działać lepiej niż duże, ale ma to znaczenie tylko wtedy, gdy zapisy w IndexedDB, które wykonuje aplikacja, faktycznie prowadzą do długich zadań, które blokują wątek główny i pogarszają wrażenia użytkownika. Ważne jest, aby mierzyć skuteczność, ponieważ dzięki temu wiesz, pod jakim kątem optymalizujesz kampanię.

Podsumowanie

Deweloperzy mogą używać mechanizmów pamięci masowej klienta, takich jak IndexedDB, aby poprawić wrażenia użytkowników aplikacji, nie tylko zachowując stan między sesjami, ale też skracając czas potrzebny na wczytanie stanu początkowego podczas kolejnych wizyt.

Prawidłowe korzystanie z IndexedDB może znacznie poprawić wrażenia użytkowników, ale nieprawidłowe użycie lub brak obsługi błędów może prowadzić do uszkodzenia aplikacji i niezadowolenia użytkowników.

Ponieważ pamięć masowa klienta obejmuje wiele czynników, na które nie masz wpływu, ważne jest, aby kod był dobrze przetestowany i prawidłowo obsługiwał błędy, nawet te, które początkowo wydają się mało prawdopodobne.