Miejsce na dane w internecie

Istnieje wiele różnych opcji przechowywania danych w przeglądarce. Który z nich najlepiej odpowiada Twoim potrzebom?

Z dowolnego miejsca połączenie internetowe może być niestabilne lub nieistotne, dlatego typowe funkcje progresywnych aplikacji internetowych to obsługa offline i stabilna wydajność. Nawet w idealnych środowiskach bezprzewodowych ostrożne korzystanie z pamięci podręcznej i inne techniki przechowywania danych może w znacznym stopniu poprawić wygodę użytkowników. Istnieje kilka sposobów zapisywania w pamięci podręcznej statycznych zasobów aplikacji (HTML, JavaScript, CSS, obrazów itd.) oraz danych (danych użytkownika, artykułów z wiadomościami itp.). Które rozwiązanie jest najlepsze? Ile możesz przechowywać? Jak zapobiec jego usunięciu?

Czego należy użyć?

Oto ogólna rekomendacja dotycząca przechowywania zasobów:

Interfejsy IndexedDB i Cache Storage API są obsługiwane przez każdą nowoczesną przeglądarkę. Są one asynchroniczne i nie blokują wątku głównego. Elementy te są dostępne w obiekcie window, w skryptach internetowych i skryptach service worker, dzięki czemu można ich łatwo używać w dowolnym miejscu w kodzie.

Co z innymi mechanizmami przechowywania danych?

W przeglądarce dostępnych jest kilka innych mechanizmów przechowywania danych, ale ich użycie jest ograniczone i mogą powodować poważne problemy z wydajnością.

Parametr SessionStorage jest ograniczony do czasu działania karty i jest ograniczony do czasu jej działania. Może być przydatna do przechowywania niewielkich ilości informacji dotyczących sesji, na przykład klucza IndexedDB. Używaj go z rozwagą, ponieważ jest synchroniczne i blokuje wątek główny. Jego rozmiar jest ograniczony do około 5 MB i może zawierać tylko ciągi tekstowe. Ponieważ jest on specyficzny dla poszczególnych kart, nie ma go dla procesów internetowych ani service worker.

Nie należy używać funkcji LocalStorage, ponieważ jest synchroniczna i blokuje wątek główny. Rozmiar pliku nie może przekraczać 5 MB i może zawierać tylko ciągi tekstowe. Usługa LocalStorage nie jest dostępna dla instancji roboczych i skryptów service worker.

Pliki cookie mają swoje zastosowania, ale nie powinny być używane do przechowywania danych. Pliki cookie są wysyłane z każdym żądaniem HTTP, więc przechowywanie większych ilości danych znacznie zwiększa rozmiar każdego żądania sieciowego. Są one synchroniczne i nie są dostępne dla robotów internetowych. Podobnie jak LocalStorage i SessionStorage, pliki cookie są ograniczone do samych ciągów znaków.

Interfejsy File System API i FileWriter API zapewniają metody odczytu i zapisu plików w systemie plików działającym w trybie piaskownicy. Chociaż jest asynchroniczny, nie jest zalecany, ponieważ jest dostępny tylko w przeglądarkach opartych na Chromium.

Interfejs File System Access API został zaprojektowany tak, aby ułatwić użytkownikom odczytywanie i edytowanie plików w lokalnym systemie plików. Aby strona mogła odczytywać lub zapisywać w jakichkolwiek plikach lokalnych uprawnienia, musi je przyznać. Uprawnienia nie są zachowywane pomiędzy sesjami.

Nie należy używać bazy danych WebSQL, a istniejące wykorzystanie należy przenieść do IndexedDB. Obsługa została usunięta z prawie wszystkich głównych przeglądarek. W 2010 r. agencja W3C przestała utrzymywać specyfikację Web SQL bez żadnych dalszych aktualizacji.

Nie należy używać pamięci podręcznej aplikacji, a dotychczasowe wykorzystanie należy przenieść do mechanizmów Service Worker i interfejsu Cache API. Została wycofana, a w przyszłości nie będzie można jej obsługiwać.

Ile mogę przechowywać?

Krótko mówiąc, dużo, co najmniej kilkaset megabajtów, a potencjalnie setki gigabajtów i więcej. Implementacje przeglądarek mogą się różnić, ale ilość dostępnego miejsca na dane zwykle zależy od ilości miejsca dostępnego na urządzeniu.

  • Chrome pozwala przeglądarce wykorzystać do 80% całego miejsca na dysku. Źródło może zająć do 60% całkowitej przestrzeni dysku. Aby określić maksymalny dostępny limit, możesz użyć interfejsu StorageManager API. Inne przeglądarki oparte na Chromium mogą wyglądać inaczej.
    • W trybie incognito Chrome zmniejsza ilość pamięci wykorzystywanej przez źródło do około 5% całkowitej przestrzeni na dysku.
    • Jeśli użytkownik włączył opcję „Wyczyść pliki cookie i dane witryn w momencie zamknięcia wszystkich okien” w Chrome, limit miejsca na dane zostanie znacznie zmniejszony do maksymalnie około 300 MB.
    • Szczegółowe informacje o implementacji Chrome znajdziesz w PR #3896.
  • Przeglądarka Internet Explorer 10 i nowsze mogą przechowywać do 250 MB. Użytkownik wyświetli pytanie, gdy wykorzystane zostanie ponad 10 MB miejsca.
  • Firefox umożliwia przeglądarce wykorzystanie do 50% wolnego miejsca na dysku. Grupa eTLD+1 (np. example.com, www.example.com i foo.bar.example.com) mogą używać do 2 GB. Ilość dostępnego miejsca możesz określić za pomocą interfejsu StorageManager API.
  • Przeglądarka Safari (zarówno na komputerze, jak i na urządzeniu mobilnym) zezwala na ok. 1 GB. Po osiągnięciu limitu Safari wyświetli użytkownikowi prośbę, zwiększając limit o 200 MB. Nie udało mi się znaleźć żadnych oficjalnych dokumentów na ten temat.
    • Dodanie aplikacji PWA do ekranu głównego w mobilnej wersji Safari wydaje się utworzyć nowy kontener pamięci i nic nie jest współdzielone między tą aplikacją a mobilną przeglądarką Safari. Po osiągnięciu limitu dla zainstalowanej aplikacji PWA nie można już poprosić o dodatkowe miejsce.

W przeszłości, jeśli witryna przekroczyła określony próg ilości przechowywanych danych, przeglądarka prosiła użytkownika o przyznanie uprawnień do korzystania z większej ilości danych. Jeśli na przykład ilość miejsca w pierwotnym miejscu przekroczy 50 MB, przeglądarka wyświetli użytkownikowi prośbę o zezwolenie na przechowywanie do 100 MB, a następnie ponawia zapytanie co 50 MB.

Obecnie większość nowoczesnych przeglądarek nie prosi użytkownika o zgodę i pozwoli witrynie wykorzystać przydzielony limit miejsca. Wyjątkiem jest przeglądarka Safari, która wyświetla komunikat po przekroczeniu limitu miejsca na dane i prosi o pozwolenie na zwiększenie przydzielonego limitu. Jeśli źródło próbuje wykorzystać więcej niż przypisany do niego limit, kolejne próby zapisu danych zakończą się niepowodzeniem.

Jak sprawdzić ilość dostępnego miejsca?

W wielu przeglądarkach za pomocą interfejsu StorageManager API możesz określić ilość miejsca dostępnego dla źródła oraz ilość zajmowanego miejsca. Raportuje łączną liczbę bajtów używanych przez IndexedDB i Cache API oraz umożliwia obliczenie przybliżonego pozostałego dostępnego miejsca.

if (navigator.storage && navigator.storage.estimate) {
  const quota = await navigator.storage.estimate();
  // quota.usage -> Number of bytes used.
  // quota.quota -> Maximum number of bytes available.
  const percentageUsed = (quota.usage / quota.quota) * 100;
  console.log(`You've used ${percentageUsed}% of the available storage.`);
  const remaining = quota.quota - quota.usage;
  console.log(`You can write up to ${remaining} more bytes.`);
}

Interfejs StorageManager nie został jeszcze zaimplementowany we wszystkich przeglądarkach, więc musisz go wykryć, zanim go użyjesz. Nawet gdy jest dostępny, musisz wychwytywać błędy przekroczenia limitu (patrz poniżej). W niektórych przypadkach może się zdarzyć, że dostępny limit przekroczy rzeczywistą ilość dostępnego miejsca.

Sprawdzanie

W trakcie programowania możesz użyć Narzędzi deweloperskich w przeglądarce, aby sprawdzić różne typy pamięci masowej i łatwo wyczyścić wszystkie zapisane dane.

W Chrome 88 dodaliśmy nową funkcję, która pozwala zastąpić limit miejsca na dane witryny w panelu pamięci. Ta funkcja umożliwia symulowanie różnych urządzeń i testowanie działania aplikacji w sytuacjach niskiego poziomu dostępności dysku. Kliknij Aplikacja, a następnie Miejsce na dane, zaznacz pole wyboru Symuluj niestandardowy limit miejsca na dane i wpisz dowolną prawidłową liczbę, aby przeprowadzić symulację limitu miejsca na dane.

Okienko Pamięć Narzędzi deweloperskich.

Pracując nad tym artykułem, napisałam proste narzędzie, które pozwala szybko wykorzystać jak najwięcej miejsca na dane. To szybki i łatwy sposób na eksperymentowanie z różnymi mechanizmami pamięci masowej oraz sprawdzenie, co się stanie, gdy wykorzystasz cały limit.

Jak sobie radzić z przekroczeniem limitu?

Co należy zrobić po przekroczeniu limitu? Przede wszystkim należy zawsze wykrywać i eliminować błędy zapisu – niezależnie od tego, czy są to błędy QuotaExceededError czy coś innego. Następnie w zależności od projektu aplikacji zdecyduj, jak ją obsługiwać. Możesz na przykład usunąć treści, z których nie korzystano od dawna, dane na podstawie rozmiaru lub umożliwić użytkownikom wybór treści do usunięcia.

Po przekroczeniu dostępnego limitu zarówno interfejs IndexedDB, jak i interfejs Cache API zwracają żądanie DOMError o nazwie QuotaExceededError.

IndexedDB

Jeśli źródło przekroczy limit, próby zapisu w IndexedDB zakończą się niepowodzeniem. Zostanie wywołany moduł obsługi onabort() transakcji przekazujący zdarzenie. Zdarzenie będzie zawierać element DOMException we właściwości błędu. Sprawdzanie błędu name zwraca wartość QuotaExceededError.

const transaction = idb.transaction(['entries'], 'readwrite');
transaction.onabort = function(event) {
  const error = event.target.error; // DOMException
  if (error.name == 'QuotaExceededError') {
    // Fallback code goes here
  }
};

Interfejs API pamięci podręcznej

Jeśli źródło przekroczy limit, próby zapisu w interfejsie Cache API będą odrzucane z użyciem QuotaExceededError DOMException.

try {
  const cache = await caches.open('my-cache');
  await cache.add(new Request('/sample1.jpg'));
} catch (err) {
  if (error.name === 'QuotaExceededError') {
    // Fallback code goes here
  }
}

Jak działa usuwanie?

Miejsce na dane w internecie jest podzielone na 2 zasobniki: „Najlepszy wybór” i „Trwałe”. Odpowiednia pamięć może zostać wyczyszczona przez przeglądarkę bez zakłócania działania użytkownika, ale w przypadku danych długoterminowych lub krytycznych jest to mniej trwałe. Pamięć trwała nie jest automatycznie czyszczona, gdy zaczyna brakować miejsca. Użytkownik musi ręcznie wyczyścić tę pamięć (za pomocą ustawień przeglądarki).

Domyślnie dane witryny (w tym dane IndexedDB, Cache API itp.) należą do kategorii najlepszych wyników. Oznacza to, że jeśli witryna nie żąda stałej pamięci masowej, przeglądarka może według własnego uznania trwale usunąć dane witryny, np. gdy jest mało miejsca na urządzeniu.

Zasada trwałego usuwania pozwala:

  • Gdy w przeglądarce zabraknie miejsca, przeglądarki oparte na Chromium zaczną usuwać dane z najrzadziej używanych źródeł, a następnie z kolejnego, aż do wyczerpania limitu.
  • Internet Explorer 10 i nowsze nie usuwają danych, ale nie będą już mogły zapisywać danych w źródle.
  • Przeglądarka Firefox rozpocznie usuwanie danych po zapełnieniu dostępnego miejsca na dysku, najpierw usuwając wszystkie dane witryn z najdawniej używanego źródła, a następnie kolejne, aż do wyczerpania limitu.
  • Wcześniej w przeglądarce Safari dane nie były trwale usuwane, ale niedawno wprowadziliśmy nowy 7-dniowy limit pamięci dostępnej do zapisu (patrz poniżej).

Począwszy w systemach iOS i iPadOS 13.4 i Safari 13.1 w systemie macOS, obowiązuje 7-dniowy limit miejsca na przechowywanie skryptów, w tym IndexedDB, rejestrację skryptu service worker i interfejs Cache API. Oznacza to, że po 7 dniach używania Safari wszystkie treści zostaną usunięte z pamięci podręcznej, jeśli użytkownik nie wejdzie w interakcję z witryną. Ta zasada usuwania nie dotyczy zainstalowanych aplikacji PWA dodanych do ekranu głównego. Szczegółowe informacje znajdziesz w sekcji Pełne blokowanie plików cookie innych firm i inne informacje na blogu WebKit.

Dodatkowe informacje: dlaczego warto używać otoki w przypadku IndexedDB

IndexedDB to interfejs API niskiego poziomu, który przed użyciem wymaga zaawansowanej konfiguracji, co może być szczególnie trudne w przypadku przechowywania prostych danych. W przeciwieństwie do większości nowoczesnych interfejsów API opartych na obietnicach, jest to metoda oparta na zdarzeniach. Obiecujące kody, takie jak idb w przypadku IndexedDB, ukrywają niektóre zaawansowane funkcje, ale co ważniejsze, ukryj złożone maszyny (np. transakcje czy obsługę wersji schematów) udostępniane przez bibliotekę IndexedDB.

Podsumowanie

Minęły już czasy, gdy miejsca na dane było ograniczone, a użytkownik musiał przechowywać coraz więcej danych. Witryny mogą skutecznie przechowywać wszystkie potrzebne zasoby i dane. Za pomocą interfejsu StorageManager API możesz określić, ile masz możliwości, a ile zostało już wykorzystane. W przypadku pamięci trwałej, chyba że użytkownik ją usunie, możesz zabezpieczyć się przed trwałym usunięciem danych.

Dodatkowe materiały

Dziękujemy

Szczególne podziękowania dla Jarryda Goodmana, Phila Waltona, Eiji Kitamury, Daniela Murphy'ego, Darwina Huanga, Josha Bella, Marijn Kruisselbrink i Victora Costana za przeczytanie tego artykułu. Dziękujemy Eiji Kitamurze, Addy Osmani i Markowi Cohenowi, którzy napisali oryginalne artykuły, na podstawie których powstała ta historia. Eiji napisał przydatne narzędzie o nazwie Browser Storage Abuser, które posłużyło do weryfikacji bieżącego zachowania. Dzięki niej możesz przechowywać jak najwięcej danych i sprawdzać limity miejsca w przeglądarce. Dzięki Francois Beaufortowi, który dokładnie sprawdził limity miejsca w Safari.

Baner powitalny autorstwa Guillaume'a Bolduca z serii Unsplash.