Honza Malý25.4.2018Zpět

Offline v prohlížeči 2. - Service Workers

V prvním dílu jsme se zabývali offline provozem v prohlížeči obecně, naznačili způsob detekce a vysvětlili, co je AppCache.

Jak z mého posouzení plyne, AppCache odpovídá na některé naše otázky, ale bohužel jich celkem dost otevírá. Zřejmě i to je důvod, proč je dnes zastaralé a doporučuje se sáhnout po alternativě, a tou jsou...

Service Workers

Když se povídáte na předchozí kapitolu, zejména AppCache API, určitě si pomyslíte: jak by bylo skvělé ovládat aplikační cache přímo, programátorsky!

Což při dalším zamyšlení není úplně triviální. Vyžaduje to mít přístup k prohlížeči tak trochu mimo DOM, mít možnost ovlivnit, jak pracuje s dokumenty. Takový skript by musel bydlet a spouštět se někde „mezi“ záložkami prohlížeče.

Dobrá zpráva je, že něco takového je možné - objevme spolu Service Workers (SW).

Service Workers: o co jde

elmi dobrý popis najdete přímo na google developers, ze kterého vychází i příklady které uvádíme níže.

  • Service Worker je JavaScript Worker, tedy kus kódu, který žije izolovaně, neumí přistoupit k DOM a používá messaging (postMessage) jako svůj primární komunikační nástroj.

  • Zároveň se chová jako programovatelné proxy, které vám umožní kompletní kontrolu nad requesty z vašeho webu.

  • Má krátký životní cyklus a není tedy vhodný k ukládání a udržování dat.

  • Využívá konceptu Promises.

Registrace

Registraci kódu provedeme takto:

navigator.serviceWorker.register('/sw.js');

sw.js je kód našeho SW, a register vrací Promise – je tedy možné detekovat, zda registrace byla úspěšná nebo ne.

V moderním prohlížeči pak většinou existuje způsob, jak si aktivní Service Workery prohlédnout, v Chrome např. zadáním adresy chrome://inspect/#service-workers.

Service Workers in Chrome
Obrázek: Service Workers v Chrome

Service Worker - fáze běhu

Service Worker ve svém kódu pracuje s událostmi, na které definujete odezvu.

Ve fázi install provedete kroky, které se inicializují při prvním spuštění SW. Například - chceme offline režim, je tedy nutné vzít soubory a vložit je do cache. K tomu slouží cache interface:

var CACHE_NAME = 'nazev-vasi-cache';
var urlsToCache = [
  '/',
  '/styles/main.css',
  '/script/main.js'
];

self.addEventListener('install', function(event) {
  event.waitUntil(
    caches.open(CACHE_NAME)
      .then(function(cache) {
        return cache.addAll(urlsToCache);
      })
  );
});

(nelze si nevšimnout, že všechny funkce zde použité pracují v plné míře s konceptem Promises. Je nutné mít tento koncept v malíku, abyste mohli napsat funkční Service Worker).

Dále máme fázi fetch, která se zavolá v okamžiku jakéhokoliv HTTP požadavku na síť.

V nejjednodušším případě, pojďme servírovat z cache, když tam najdeme daný zdroj:

self.addEventListener('fetch', function(event) {
  event.respondWith(
    caches.match(event.request)
      .then(function(response) {       
        if (response) {
          return response;
        }
        return fetch(event.request);
      }
    )
  );
});

Samozřejmě je možné toto dále zdokonalovat. Máte přeci k dispozici kompletní, programovatelné rozhraní! Je tak možné na základě event.request HTTP požadavky klasifikovat, například rozhodnout, že jej uložíte do cache a následně vrátíte cachovaný... dobře to popisuje zmíněná dokumentace od Google.

Fáze Service Workers
Obrázek: Jednotlivé životní cykly pro Service Worker. Zdroj: Google Developers.

Service Worker a Update

Stejně jako u AppCache, i zde platí: změní-li se byť jeden bajt souboru s definicí SW, prohlížeč se jej pokusí obnovit (přesněji řečeno, uvažuje, že je nový).

V takovém případě dojde ke spuštění nového skriptu a spustí se install fáze.

Nicméně, starý Service Worker stále má pod kontrolou vše, co se na webu přes fetch nahrává. Nový je vedený ve stavu waiting.

Až v okamžiku, kdy se všechny aktuálně otevřené stránky vašeho webu zavřou (fyzickým zavřením záložky prohlížeče), starý Service Worker se zničí a nahradí se novým. Také se spustí událost activate v okamžiku, kdy nový Service Worker převezme kontrolu.

Událost activate je tak pro nás důležitá, pokud chceme po starém SW uklidit, například vyčistit cache. Dá se vyřešit callbackem vázaným na event activate.

Service Workers: Speciality a problémy

  • Na webu je nutné mít aktivní HTTPS, a to i při vývoji na localhost. Google to zdůvodňuje tím, že s Service Workers dostáváte do rukou mocnou zbraň a tak je třeba bránit se zejména útokům man-in-the-middle.

  • Podpora v prohlížečích. Aktuální stav najdete na github pages od Jake Archibalda a sami vidíte, není to úplně optimální. Situace se změní zejména, až je adoptuje Safari a Edge, ale u Internet Exploreru se prostě už nedočkáte. . Update - duben 2018 - Safari už oficiálně SW podporuje.

  • Debugging. Vzhledem k tomu jak izolovaně Service Worker běží, špatně se pracuje s chybovými hláškami. V Chrome pomáhá v inspectoru pauzovat při nezachycených výjimkách.

  • Přes Fetch se nepřenáší credentials nebo cookies, takže na nich nemůžete fungování SW nějakým způsobem vázat. Lze obejít jedině tak, že při volání fetch uvedete nastavení credentials: "include".

  • Další, spíše detaily - odkážu na podrobnější povídání.

Užitečné odkazy

Poměrně nedávno jsem narazil na Service Worker Cookbook, knihovničku praktických a názorných ukázek využití SW. Od cachingu se dostanete ke složitějším scénářům, například obsluze Push notifikací.

Z podobného soudku pak doporučím repozitář Service Worker Recipes

Praxe

Service Workers dnes běžně v Kurzoru nepoužíváme zejména kvůli chybějící podpoře mezi prohlížeči. Pokud ano, většinou jako součást nějakého nástroje, který je nějakým způsobem přibaluje - například SW Precache Webpack Plugin. Každopádně by bylo pošetilé na nich v současné situaci ve vaší aplikaci nebo webu záviset, měli byste je brát jako doplněk.

Pohříchu jsme se spíš setkali s problémy, kdy někdo nasadil dříve SW neuváženě a bez jakýchkoliv znalostí technologie. Ony pak dlí v prohlížečích návštěvníků, kde mohou páchat neplechu, například znemožnit update webu díky zaseklé cache.

PRO TIP: V takovém případě se vám bude hodit neprůstřelný návod k odstranění všech SW z dané webové stránky při jejím dalším načtení - odkaz na repozitář. Trik je v tom, že zavoláte „self-destroying“ Service Worker, který po sobě a ostatních prostě uklidí.

Závěrem

Doufám že náš krátký seriál se vám líbil a vysvětlil odpovídajícím způsobem, proti čemu dnes na poli offline provozu v prohlížeči stojíme a s čím můžeme počítat.

Honza Malý
maly@kurzor.net
+420 722 211 443
Honza se specializuje na návrh webů a UI, věnuje se také vývoji.

Seriál: Offline

Offline v prohlížeči 1. - Detekce, AppCache

Proměňte offline režim ve výhodu a připravte na něj váš web nebo aplikaci - první část našeho pojednání.

Honza Malý4.1.2018