Typowe techniki tworzenia aplikacji offline

Jake Archibald
Jake Archibald

Dzięki Service Workers udostępniliśmy programistom sposób na rozwiązanie problemu z połączeniem sieciowym. Masz kontrolę nad buforowaniem i sposobem obsługi żądań. Oznacza to, że możesz tworzyć własne wzory. Przyjrzyj się kilku możliwym wzorcom w izolacji, ale w praktyce prawdopodobnie będziesz ich używać jednocześnie, w zależności od adresu URL i kontekstu.

Przykłady niektórych z tych wzorców znajdziesz w Trained-to-thrill.

Kiedy przechowywać zasoby

Browser Support

  • Chrome: 40.
  • Edge: 17.
  • Firefox: 44.
  • Safari: 11.1.

Source

Skrypty service worker umożliwiają obsługę żądań niezależnie od buforowania, dlatego pokażę je osobno. Najpierw ustal, kiedy warto używać pamięci podręcznej.

Podczas instalacji jako zależność

Podczas instalacji jako zależność.

Interfejs Service Worker API udostępnia zdarzenie install. Możesz go użyć, aby przygotować elementy, które muszą być gotowe przed obsługą innych zdarzeń. Podczas install poprzednie wersje skryptu service worker działają i obsługują strony. Wszelkie działania podejmowane w tym czasie nie powinny zakłócać działania dotychczasowego service workera.

Idealne rozwiązanie w przypadku: plików CSS, obrazów, czcionek, JS, szablonów i wszystkiego innego, co w danej wersji witryny uważasz za statyczne.

Pobieraj elementy, które w przypadku niepowodzenia pobierania spowodują, że witryna przestanie działać, oraz elementy, które odpowiednia aplikacja na konkretną platformę uwzględniłaby w początkowym pobieraniu.

self.addEventListener('install', function (event) {
  event.waitUntil(
    caches.open('mysite-static-v3').then(function (cache) {
      return cache.addAll([
        '/css/whatever-v3.css',
        '/css/imgs/sprites-v6.png',
        '/css/fonts/whatever-v8.woff',
        '/js/all-min-v4.js',
        // etc.
      ]);
    }),
  );
});

event.waitUntil przyjmuje obietnicę określenia długości i skuteczności instalacji. Jeśli obietnica zostanie odrzucona, instalacja zostanie uznana za nieudaną, a ten skrypt service worker zostanie porzucony (jeśli działa starsza wersja, pozostanie ona nienaruszona). caches.open()cache.addAll() obietnice zwrotu. Jeśli nie uda się pobrać żadnego z zasobów, wywołanie cache.addAll() zostanie odrzucone.

Na stronie trained-to-thrill używam tego do buforowania statycznych komponentów.

Podczas instalacji, a nie jako zależność

Podczas instalacji, a nie jako zależność.

Jest to podobne do instalowania jako zależności, ale nie opóźnia zakończenia instalacji i nie powoduje jej niepowodzenia w przypadku niepowodzenia buforowania.

Idealne rozwiązanie w przypadku: większych zasobów, które nie są potrzebne od razu, np. elementów do późniejszych poziomów gry.

self.addEventListener('install', function (event) {
  event.waitUntil(
    caches.open('mygame-core-v1').then(function (cache) {
      cache
        .addAll
        // levels 11-20
        ();
      return cache
        .addAll
        // core assets and levels 1-10
        ();
    }),
  );
});

Ten przykład nie przekazuje z powrotem do cache.addAll obietnicy dotyczącej poziomów 11–20, więc nawet jeśli się nie powiedzie, gra będzie nadal dostępna offline.event.waitUntil Oczywiście musisz uwzględnić możliwość braku tych poziomów i ponownie spróbować je zapisać w pamięci podręcznej, jeśli ich nie ma.

Proces service worker może zostać zakończony podczas pobierania poziomów 11–20, ponieważ zakończył obsługę zdarzeń, co oznacza, że nie zostaną one zapisane w pamięci podręcznej. Web Periodic Background Synchronization API może obsługiwać takie przypadki, a także większe pobierania, np. filmów.

Browser Support

  • Chrome: 40.
  • Edge: 17.
  • Firefox: 44.
  • Safari: 11.1.

Source

Po aktywacji

Po aktywacji

Idealny do: czyszczenia i migracji.

Gdy nowy skrypt service worker zostanie zainstalowany, a poprzednia wersja nie będzie używana, nowy skrypt zostanie aktywowany i otrzymasz zdarzenie activate. Ponieważ poprzednia wersja nie jest już potrzebna, to dobry moment na przeprowadzenie migracji schematu w IndexedDB i usunięcie nieużywanych pamięci podręcznych.

self.addEventListener('activate', function (event) {
  event.waitUntil(
    caches.keys().then(function (cacheNames) {
      return Promise.all(
        cacheNames
          .filter(function (cacheName) {
            // Return true if you want to remove this cache,
            // but remember that caches are shared across
            // the whole origin
          })
          .map(function (cacheName) {
            return caches.delete(cacheName);
          }),
      );
    }),
  );
});

Podczas aktywacji zdarzenia takie jak fetch są umieszczane w kolejce, więc długotrwała aktywacja może blokować wczytywanie stron. Zadbaj o to, aby aktywacja była jak najprostsza, i używaj jej tylko do czynności, których nie można było wykonać, gdy aktywna była poprzednia wersja.

Na stronie trained-to-thrill używam tego do usuwania starych pamięci podręcznych.

Przy interakcji użytkownika

Przy interakcji użytkownika.

Idealne rozwiązanie: gdy nie można udostępnić całej witryny w trybie offline i zdecydowano, że użytkownik będzie mógł wybrać treści, które mają być dostępne offline. np. film w YouTube, artykuł w Wikipedii lub konkretna galeria na Flickrze.

Udostępnij użytkownikowi przycisk „Przeczytaj później” lub „Zapisz do odczytu offline”. Gdy użytkownik kliknie link, pobierz potrzebne informacje z sieci i zapisz je w pamięci podręcznej.

document.querySelector('.cache-article').addEventListener('click', function (event) {
  event.preventDefault();

  var id = this.dataset.articleId;
  caches.open('mysite-article-' + id).then(function (cache)