Pracovníci služeb jsou mocní a rozhodně stojí za to se je naučit. Umožňují poskytovat uživatelům zcela novou úroveň služeb. Váš web se může načíst okamžitě. Může fungovat i v režimu offline. Může být nainstalován jako nativní aplikace a působit stejně uhlazeně – ale s dosahem a svobodou webu.

Service workers se však nepodobají ničemu, na co je většina z nás, webových vývojářů, zvyklá. Přicházejí se strmou křivkou učení a hrstkou zádrhelů, na které si musíte dávat pozor.

Google Developers a já jsme nedávno spolupracovali na projektu – Service Workies – bezplatné hře pro pochopení service workers. Při jejím vytváření a práci se složitými zákoutími servisních pracovníků jsem narazil na několik zádrhelů. Nejvíce mi pomohlo vymyslet hrst zobrazujících metafor. V tomto příspěvku tyto mentální modely prozkoumáme a omotáme si kolem prstu paradoxní vlastnosti, díky nimž jsou pracovníci služeb záludní i úžasní.

Stejní, ale jiní #

Při kódování pracovníka služeb vám bude mnoho věcí připadat povědomých. Budete moci používat své oblíbené nové vlastnosti jazyka JavaScript. Nasloucháte událostem životního cyklu stejně jako u událostí uživatelského rozhraní. Řídíte tok řízení pomocí slibů, jak jste zvyklí.

Jiné chování service workeru však způsobí, že se budete zmateně škrábat na hlavě. Zvláště když obnovíte stránku a nevidíte, že se změny vašeho kódu uplatnily.

Nová vrstva #

Obvykle při vytváření webu myslíte jen na dvě vrstvy: klienta a server. Service worker je zcela nová vrstva, která se nachází uprostřed.

Představte si service worker jako jakési rozšíření prohlížeče – takové, které si váš web může nainstalovat do prohlížeče uživatele. Po instalaci pracovník služeb rozšíří prohlížeč vašeho webu o výkonnou prostřední vrstvu. Tato vrstva service worker může zachytit a zpracovat všechny požadavky, které váš web zadá.

Vrstva service worker má svůj vlastní životní cyklus nezávislý na kartě prohlížeče. K aktualizaci service workeru nestačí pouhé obnovení stránky – stejně jako byste neočekávali, že obnovení stránky aktualizuje kód nasazený na serveru. Každá vrstva má svá vlastní jedinečná pravidla pro aktualizaci.

Ve hře Service Workies se věnujeme mnoha podrobnostem životního cyklu service workerů a poskytneme vám spoustu praxe při práci s nimi.

Představte si service worker jako novou střední vrstvu s vlastním životním cyklem a metodami pro aktualizaci.

Mocný, ale omezený #

Mít na webu service worker vám přináší neuvěřitelné výhody. Váš web může:

  • pracovat bezchybně, i když je uživatel offline
  • získat obrovské zlepšení výkonu díky ukládání do mezipaměti
  • používat push oznámení
  • být nainstalován jako PWA

Při tom všem, co service workers umí, jsou z principu omezené. Nemohou dělat nic synchronně nebo ve stejném vlákně jako váš web. To tedy znamená, že nemají přístup k:

  • localStorage
  • domu
  • oknu

Dobrou zprávou je, že existuje několik způsobů, jak může vaše stránka komunikovat se svým service workerem, včetně přímé postMessage, kanálů zpráv one-to-one a kanálů vysílání one-to-many.

Představte si service worker jako něco, co žije mimo vaši stránku. Můžete s ním komunikovat, ale nemá přímý přístup k vaší stránce.

Dlouhodobý, ale krátkodobý #

Aktivní servisní pracovník žije dál i poté, co uživatel opustí vaši stránku nebo zavře kartu. Prohlížeč si tento servisní pracovník ponechává, aby byl připraven, až se uživatel příště na váš web vrátí. Ještě před odesláním prvního požadavku dostane service worker šanci jej zachytit a převzít kontrolu nad stránkou. Právě to umožňuje, aby web fungoval offline – service worker může sám obsluhovat verzi stránky uloženou v mezipaměti, i když uživatel nemá připojení k internetu.

V Service Workies si tento koncept představujeme pomocí Kolohe (přátelského service workeru), který zachycuje a obsluhuje požadavky.

Zastaveno #

Přestože se service workery zdají být nesmrtelné, lze je téměř kdykoli zastavit. Prohlížeč nechce plýtvat prostředky na pracovníka služby, který právě nic nedělá. Zastavení není totéž co ukončení – servisní pracovník zůstává nainstalován a aktivován. Je pouze uspán. Až ho bude příště potřeba (např. k vyřízení požadavku), prohlížeč ho znovu probudí.

waitUntil #

Vzhledem k neustálé možnosti uspání potřebuje váš servisní pracovník způsob, jak dát prohlížeči najevo, že dělá něco důležitého a nechce si zdřímnout. Zde přichází na řadu event.waitUntil(). Tato metoda prodlužuje životní cyklus, ve kterém je použita, a zabraňuje jak jejímu zastavení, tak přechodu do další fáze jejího životního cyklu, dokud nebudeme připraveni. To nám dává čas na nastavení mezipaměti, načtení zdrojů ze sítě atd.

Tento příklad říká prohlížeči, že náš servisní pracovník neskončí s instalací, dokud nebude vytvořena mezipaměť assets a naplněna obrázkem meče:

self.addEventListener("install", event => {
event.waitUntil(
caches.open("assets").then(cache => {
return cache.addAll();
})
);
});

Pozor na globální stav #

Když dojde k tomuto spuštění/zastavení, je resetován globální rozsah servisního pracovníka. Dávejte si proto pozor, abyste ve svém service workeru nepoužívali žádný globální stav, jinak budete smutní, až se příště znovu probudí a bude mít jiný stav, než jaký očekával.

Podívejte se na tento příklad, který používá globální stav:

const favoriteNumber = Math.random();
let hasHandledARequest = false;
self.addEventListener("fetch", event => {
console.log(favoriteNumber);
console.log(hasHandledARequest);
hasHandledARequest = true;
});

Při každém požadavku tento service worker zaznamená číslo – řekněme 0.13981866382421893. Proměnná hasHandledARequest se také změní na true. Nyní je service worker chvíli nečinný, takže jej prohlížeč zastaví. Při příštím požadavku je servisní pracovník opět potřeba, takže jej prohlížeč probudí. Jeho skript se znovu vyhodnotí. Nyní je hasHandledARequest resetováno na false a favoriteNumber je něco úplně jiného – 0.5907281835659033.

Nemůžete se spoléhat na uložený stav v service workeru. Také vytváření instancí věcí, jako jsou kanály zpráv, může způsobit chyby: při každém zastavení/spuštění service workeru získáte zcela novou instanci.

Upozornění: Tento zádrhel je třeba mít na paměti zejména při práci na kódu service workeru, protože při otevřeném nástroji Chrome DevTools je chování při spuštění/zastavení zakázáno. Chyby způsobené spoléháním na globální stav si můžete všimnout až po jejich odeslání uživatelům.

V kapitole 3 Service Workies jsme si náš zastavený service worker představili jako ztrátu všech barev, zatímco čeká na probuzení.

Představte si svůj service worker jako psa bičíka. Je rychlý, věrný a úžasný. Bude vám stát po boku, ať se děje, co se děje. Ale většinou chce jen spát. Pořád. Musíte mu dát najevo, kdy chcete, aby zůstal vzhůru. Hodný pes!“

Společně, ale odděleně #

Vaši stránku může ovládat vždy jen jeden pracovník služby. Může však mít nainstalovány dva servisní pracovníky najednou. Když provedete změnu v kódu service workeru a obnovíte stránku, ve skutečnosti vůbec neupravujete service worker. Servisní pracovníci jsou neměnní. Místo toho vytváříte zcela nový. Tento nový pracovník služby (říkejme mu SW2) se nainstaluje, ale ještě se neaktivuje. Musí počkat na ukončení stávajícího service workeru (SW1) (až uživatel opustí váš web).

Hrátky s mezipamětí jiného service workeru #

Při instalaci může SW2 provádět nastavení – obvykle vytvářet a plnit mezipaměť. Ale pozor: tento nový service worker má přístup ke všemu, k čemu má přístup současný service worker. Pokud si nedáte pozor, může nový čekající servisní pracovník současnému servisnímu pracovníkovi pořádně zavařit. Několik příkladů, které by vám mohly způsobit potíže:

  • SW2 by mohl odstranit mezipaměť, kterou SW1 aktivně používá.
  • SW2 by mohl upravit obsah mezipaměti, kterou SW1 používá, což by způsobilo, že by SW1 odpověděl prostředky, které stránka neočekává.

Skip skipWaiting #

Pracovník služby může také použít riskantní metodu skipWaiting(), aby převzal kontrolu nad stránkou, jakmile dokončí instalaci. To je obecně špatný nápad, pokud se záměrně nesnažíte nahradit chybný service worker. Nový pracovník služby by mohl používat aktualizované prostředky, které aktuální stránka neočekává, což by vedlo k chybám a chybám.

Začněte čistě #

Způsob, jak zabránit tomu, aby se pracovníci služby navzájem zahlcovali, je zajistit, aby používali různé mezipaměti. Nejjednodušší způsob, jak toho dosáhnout, je verzovat názvy cache, které používají.

const version = 1;
const assetCacheName = `assets-${version}`;
self.addEventListener("install", event => {
caches.open(assetCacheName).then(cache => {
// confidently do stuff with your very own cache
});
});

Při nasazení nového service workeru narazíte na version, aby dělal, co potřebuje, se zcela oddělenou cache od předchozího service workeru.

End clean #

Jakmile váš service worker dosáhne stavu activated, víte, že převzal úlohu a předchozí service worker je nadbytečný (tj, již není potřeba). V tomto okamžiku je důležité po starém service workeru uklidit. Nejenže to respektuje limity úložiště mezipaměti vašich uživatelů, ale může to také zabránit nechtěným chybám.

Metoda caches.match() je často používaná zkratka pro načtení položky z libovolné mezipaměti, kde je shoda. Prochází však keše v pořadí, v jakém byly vytvořeny. Řekněme tedy, že máte dvě verze souboru skriptu app.js ve dvou různých keších – assets-1 a assets-2. Vaše stránka očekává novější skript, který je uložen v assets-2. Ale pokud jste neodstranili starou mezipaměť, caches.match('app.js') vrátí tu starou z assets-1 a s největší pravděpodobností rozbije vaši stránku.

K úklidu po předchozích servisních pracovnících stačí smazat veškerou mezipaměť, kterou nový servisní pracovník nepotřebuje:

const version = 2;
const assetCacheName = `assets-${version}`;
self.addEventListener("activate", event => {
event.waitUntil(
caches.keys().then(cacheNames => {
return Promise.all(
cacheNames.map(cacheName => {
if (cacheName !== assetCacheName){
return caches.delete(cacheName);
}
});
);
});
);
});

Zabránit tomu, aby se servisní pracovníci navzájem potírali, vyžaduje trochu práce a disciplíny, ale stojí to za to.

Představte si kombinaci servisního pracovníka a webu jako instalovatelnou aplikaci. Každá verze by měla fungovat. Každá verze by měla být oddělená od ostatních. Představte si, jak chybná by byla hra, kdyby vývojář omylem vydal patch, který by používal novou herní logiku, ale zastaralé prostředky. To byste na fórech tak rychle zuřili! Udržujte verze aplikací uklizené &čisté.

Myšlení o servisních pracovnících #

Přemýšlení o servisních pracovnících ve správném duchu vám pomůže s jistotou vytvořit ty vaše. Jakmile si je osvojíte, budete moci vytvářet neuvěřitelné zážitky pro své uživatele.

Pokud to všechno chcete pochopit hrou, pak máte štěstí! Jděte si zahrát hru Service Workies, kde se naučíte způsoby práce pracovníka služeb, abyste mohli zabít offline bestie.

Naposledy aktualizováno: 4. června 2019 Zlepšit článek

Napsat komentář

Vaše e-mailová adresa nebude zveřejněna.