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 stworzyć początkowy stan aplikacji, który służy do renderowania interfejsu użytkownika. Czasami aplikacja musi uwierzytelnić użytkownika po stronie klienta, a potem wysłać kilka żądań do interfejsu API, aby uzyskać wszystkie dane potrzebne do wyświetlenia na stronie.

Przechowywanie stanu aplikacji w IndexedDB może być świetnym sposobem na przyspieszenie wczytywania podczas powtórnych wizyt. Aplikacja może wtedy synchronizować się z dowolnymi usługami interfejsu API w tle oraz aktualizować interfejs użytkownika z nowymi danymi, 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 interfejsów API. W tym dokumencie znajdziesz odpowiedzi na najczęstsze pytania oraz informacje o najważniejszych kwestiach, o których warto pamiętać podczas zapisywania stanu aplikacji w IndexedDB.

Zadbaj o przewidywalność aplikacji

Wiele złożoności związanych z IndexedDB wynika z faktu, że istnieje wiele czynników, na które deweloper nie ma wpływu. W tej sekcji omawiamy wiele problemów, które należy wziąć pod uwagę podczas pracy z IndexedDB.

Zapisy w pamięci mogą się nie udać

Błędy podczas zapisywania danych 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ż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.

Dlatego tak ważne jest, aby zawsze prawidłowo obsługiwać błędy w kodzie IndexedDB. Oznacza to również, że warto przechowywać stan aplikacji w pamięci (oprócz przechowywania w pamięci), aby interfejs użytkownika nie uległ uszkodzeniu podczas korzystania z trybu przeglądania prywatnego lub gdy nie ma dostępnej przestrzeni dyskowej (nawet jeśli niektóre inne funkcje aplikacji wymagające pamięci 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 przypadku możesz 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ć.

Zmiana danych przechowywanych lokalnie może być rzadka, ale ich usuwanie jest dość powszechne. Ważne jest, aby aplikacja mogła obsłużyć oba te przypadki bez błędów.

Zapisane dane mogą być nieaktualne

Podobnie jak w poprzedniej sekcji, nawet jeśli użytkownik nie zmodyfikował danych, mogą one być zapisane w pamięci masowej przez wcześniejszą wersję kodu, która prawdopodobnie zawiera błędy.

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 wersji z błędem).

W tym przypadku bardzo pomocne mogą być testy jednostkowe, ponieważ ręczne testowanie wszystkich możliwych ścieżek i przypadków uaktualniania często nie jest możliwe.

Utrzymaj wydajność aplikacji

Jedną z kluczowych funkcji IndexedDB jest asynchroniczny interfejs API, ale nie oznacza to, że nie musisz się martwić o wydajność. W niektórych przypadkach niewłaściwe użycie może zablokować główny wątek, co może spowodować brak reakcji.

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

Chociaż IndexedDB umożliwia przechowywanie dużych, zagnieżdżonych obiektów jako pojedynczych rekordów (co jest dość wygodne z perspektywy programisty), należy unikać tej praktyki. 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.

Chociaż zarządzanie stanem w ten sposób ma wiele zalet i chociaż przechowywanie całego drzewa stanu jako pojedynczego rekordu w IndexedDB może być kuszące i wygodne, robienie tego po każdej zmianie (nawet jeśli jest ona ograniczona lub opóźniona) spowoduje niepotrzebne blokowanie wątku głównego, zwiększy prawdopodobieństwo wystąpienia błędów zapisu, a w niektórych przypadkach może nawet spowodować, że karta przeglądarki przestanie odpowiadać lub się zawiesi.

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 reguła typu „wszystko albo nic”. W przypadku, gdy nie można podzielić obiektu stanu i zapisać tylko minimalnego zestawu 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ń.

Na koniec zawsze mierz wpływ kodu na wydajność. Chociaż prawdą jest, że małe operacje zapisu do IndexedDB będą działać lepiej niż duże operacje zapisu, ma to znaczenie tylko wtedy, gdy zapisy do IndexedDB wykonywane przez aplikację prowadzą do długich zadań, które blokują główny wątek i pogarszają wrażenia użytkownika. Warto je mierzyć, aby wiedzieć, do czego optymalizujesz.

Podsumowanie

Deweloperzy mogą używać mechanizmów przechowywania danych na kliencie, takich jak IndexedDB, aby poprawić wrażenia użytkowników aplikacji. Nie tylko zapisują stan w całości w trakcie sesji, ale też skracają czas potrzebny na załadowanie początkowego stanu podczas kolejnych wizyt.

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.