Strona główna / Artykuły

Włącz obsługę offline w aplikacjach internetowych za pomocą Service Workers

Pracownicy usług i Cache API sprawiają, że strona ładuje się natychmiastowo i może funkcjonować offline. Pisanie kodu pracownika, jego rejestracja oraz wybór strategii cacheowania.

Wydawca: REACTAPP.TOP5 min czytania1098 słów

Źródła: ☕ JavaScript Hack That Makes Any Website Work Offline

Załóżmy, że ktoś przegląda twoją stronę podczas jazdy pociągiem, a jego połączenie co kilka sekund się urywa i przywraca. Na większości stron internetowych takie niestabilne połączenie oznacza problem – błąd przeglądarki informuje go, że jest poza siecią. A co, jeśli twoja strona mogłaby całkowicie uniknąć tego problemu i nadal funkcjonować?

To nie jest jakaś eksperymentalna funkcja przyszłości. Można to osiągnąć już teraz dzięki technologii przeglądarki zwanej Service Worker. Service Worker działa jak skryptowy pośrednik pomiędzy twoją aplikacją internetową a siecią. Może przechwytywać żądania przed tym, jak dotrą do serwera, i samodzielnie na nie odpowiadać za pomocą plików przechowywanych lokalnie, dzięki czemu twoja strona może nadal funkcjonować nawet bez żadnego połączenia.

Ten trik służy nie tylko do zapewnienia przydatnego rozwiązania awaryjnego — może znacznie przyspieszyć czas ładowania i sprawić, że twoja aplikacja będzie znacznie bardziej odporna na problemy z siecią. I chociaż brzmi to skomplikowanie, jego konfiguracja jest dość prosta.

Czym napędza ten trik: Service Workers w połączeniu z Cache API

Dwie funkcje przeglądarki współpracują ze sobą, aby to umożliwić:

  1. Service Worker: skrypt działający w tle, niezależnie od głównej nitki strony, pełniący rolę warstwy sieciowej.
  2. Cache API: wbudowana interfejs przeglądarki, która umożliwia programowe przechowywanie i odzyskiwanie zasobów, podobnie jak magazyn typu klucz-wartość. To tutaj przechowujesz pliki HTML, CSS, JavaScript, obrazy oraz inne zasoby, od których zależy twoja strona.

Oto ogólny przebieg: za pierwszym razem, gdy ktoś odwiedza twoją stronę podłączony do Internetu, Service Worker instaluje się i pobiera ważne pliki do swojej pamięci cache. Od tego momentu każde żądanie sieciowe wysyłane przez stronę przechodzi najpierw przez Service Worker. Gdy odwiedzający traci połączenie, worker reaguje, korzystając z tego, co już ma w cache, zamiast próbować – i ponosić porażkę – połączenia z serwerem, dzięki czemu strona nadal renderowana jest niemal natychmiast.

Krok 1: Napisz skrypt Service Worker

Zacznij od stworzenia pliku o nazwie sw.js w korzeniu swojego projektu. To właśnie ten skrypt jest odpowiedzialny za instalację pamięci cache oraz przechwytywanie przyszłych żądań.

// sw.js

const CACHE_NAME = 'my-website-cache-v1';
const urlsToCache = [
  '/',
  '/index.html',
  '/styles.css',
  '/script.js',
  '/images/logo.png'
];

// The 'install' event is fired when the service worker is first installed.
self.addEventListener('install', event => {
  event.waitUntil(
    caches.open(CACHE_NAME)
      .then(cache => {
        console.log('Opened cache');
        return cache.addAll(urlsToCache);
      })
  );
});

// The 'fetch' event is fired for every network request.
self.addEventListener('fetch', event => {
  event.respondWith(
    caches.match(event.request)
      .then(response => {
        // If the request is in the cache, serve the cached version.
        if (response) {
          console.log('Serving from cache:', event.request.url);
          return response;
        }

        // Otherwise, fetch from the network.
        console.log('Fetching from network:', event.request.url);
        return fetch(event.request);
      })
  );
});

Plik ten głównie przysłuchuje się do dwóch zdarzeń cyklu życia:

  • install: tutaj otwierasz nazwany cache i wypełniasz go listą plików, które chcesz mieć dostępne nawet bez połączenia sieciowego.
  • fetch: to zdarzenie powstaje przy każdej prośbie wysyłanej przez stronę. Procesor sprawdza, czy w cache już istnieje odpowiadająca odpowiedź; jeśli tak, zwraca tę zapisaną kopię, a jeśli nie, prośba jest wysyłana do sieci jak zwykle.

Krok 2: Zarejestruj procesor w swojej aplikacji

Gdy skrypt procesora już istnieje, nadal trzeba poinformować przeglądarkę o jego użyciu. Dodaj następujący fragment do swojego głównego pliku skryptowego lub wstaw go bezpośrednio do tagu <script> w pliku HTML.

// Register the service worker
if ('serviceWorker' in navigator) {
  window.addEventListener('load', () => {
    navigator.serviceWorker.register('/sw.js')
      .then(registration => {
        console.log('Service Worker registered successfully:', registration);
      })
      .catch(error => {
        console.error('Service Worker registration failed:', error);
      });
  });
}

Ten blok najpierw sprawdza, czy aktualny przeglądarka w ogóle obsługuje API Service Worker, a jeśli tak, to rejestruje plik sw.js. Zwróć uwagę na ścieżkę używaną do jego rejestracji: /sw.js musi znajdować się w korzeniu strony, ponieważ Service Worker może kontrolować tylko te strony, które należą do zakresu katalogu, z którego został zarejestrowany.

Weryfikacja poprawności działania

Aby zobaczyć to w praktyce, otwórz swoją stronę w przeglądarce, która obsługuje Service Workers — nadają się Chrome, Firefox i Edge.

  • Otwórz narzędzia deweloperskie przeglądarki (F12 lub Ctrl+Shift+I).
  • Przejdź do panelu Application.
  • W pasku bocznym znajdź Service Workers. Twój plik sw.js powinien tam być widoczny jako aktywny.
  • Kliknij w Cache Storage, aby potwierdzić, że istnieje Twoja nazwana pamięć cache i zawiera pliki, które wymieniłeś.
  • Zaznacz pole wyboru „Offline” znajdujące się u góry sekcji Service Worker.
  • Przeładowaj stronę.
  • Jeśli wszystko jest poprawnie skonfigurowane, strona załaduje się natychmiast, mimo braku dostępu do sieci. Wyniki z konsoli w narzędziach deweloperskich potwierdzą, że żądania są przekierowywane i obsługiwane bezpośrednio z pamięci cache, a nie z sieci.

    Rozszerzanie tego podejścia: alternatywne strategie cacheowania

    To, co właśnie opisano, nazywane jest podejściem cache-first, network-fallback – doskonałym rozwiązaniem dla zasobów, które rzadko się zmieniają, takich jak statyczne obrazy lub spakowane skrypty. Jednak Service Workers nie są ograniczone tylko do tego jednego wzorca; istnieje kilka innych powszechnych strategii:

    • Network-first, cache-fallback: nadaje się do treści, które zmieniają się często i muszą pozostawać aktualne. Procesor najpierw próbuje pobrać dane z sieci, a tylko w przypadku niepowodzenia tej próby, na przykład z powodu słabej łączności, korzysta z treści z pamięci cache.
    • Stale-while-revalidate: procesor natychmiast odpowiada za pomocą treści już zapisanej w pamięci cache dla szybkości, jednocześnie wysyłając w tle żądanie do sieci w celu odświeżenia cache przed kolejnym załadowaniem strony. Dzięki temu otrzymujesz szybkie odpowiedzi już teraz, a aktualne treści wkrótce potem.

    Opanowanie tego podstawowego wzorca pracy offline umożliwia również tworzenie pełnych aplikacji Progressive Web Apps, w których obsługa pracy offline łączy się z funkcjami takimi jak powiadomienia typu push oraz możliwością instalacji strony na ekranie głównym urządzenia jak aplikacji natywnej.

    Dodanie tego wzorca do twojego projektu to stosunkowo niewielka inwestycja przynosząca znaczące korzyści: zamiast nieprawidłowego połączenia całkowicie psującego doświadczenie użytkownika, oni ledwo zauważają tę przerwę.

    Literatura pokrewna

  • Dedykowani, dzieleni i pracownicy usługowy: wybór odpowiedniej nici brausera — Dowiedz się, w jaki sposób dedykowani, dzieleni i pracownicy usługowy różnią się pod względem zakresu działania, komunikacji i celu, oraz kiedy każdy z nich faktycznie poprawia aplikację internetową.