Probeert u uit te vinden wat een servicewerker is? U bent niet de enige!
Een Service Worker is een script dat op de achtergrond wordt uitgevoerd, in een aparte thread van de browser UI. Service worker cache maakt het mogelijk voor een website om offline te functioneren. Ze zijn de technische krachtpatser die een website naar een progressive web app tillen. Ze maken diepe platformintegratie mogelijk, zoals rich caching, push notifications en background sync.
Service workers zijn ontworpen om een uitbreidbaar platform te zijn, extra functies zijn momenteel in de planning.
Ze hebben geen toegang tot de DOM, maar kunnen wel alle netwerkverzoeken onderscheppen. Dit geeft ontwikkelaars de mogelijkheid om te bepalen hoe verzoeken worden afgehandeld, waardoor een rijke manier om websites offline te laten werken.
Service workers zijn wel een game changer voor het web genoemd. Ik denk niet dat dat eenvoudig overdreven is, want ze maken veel broodnodige mogelijkheden mogelijk en maken de kernarchitectuur die ik jarenlang heb gebruikt native.
Service Workers klinken geweldig!
Dit is de sleuteltechnologie of moderne web-API achter Progressive Web Applications. Zonder een service worker een website is gewoon een website, voeg een service worker en je hebt nu een applicatie.
Er zijn een aantal belangrijke kenmerken van service workers die je moet begrijpen:
- Een service worker is een JavaScript-bestand
- Ze worden uitgevoerd op een aparte thread van de UI
- Ze hebben geen directe toegang tot het DOM
- Er is een levenscyclus of een reeks gebeurtenissen die een service worker doorloopt om actief te worden, wat later wordt uitgelegd
- Ze zijn alleen actief als ze worden gebruikt, dus geen belasting van de batterij
- Ze zijn geïsoleerd van de oorsprong of het domein waarmee ze zijn geregistreerd
- Service Workers vereisen HTTPS
- Kunnen berichten verzenden van en naar de UI
- Hebben geen open webpagina nodig om te functioneren
- Worden ondersteund door alle grote browsers, inclusief iOS Safari
- Zijn vergelijkbaar met Web Workers, maar in veel opzichten beter
- Hoe werken Service Workers?
- Service Worker Extensibility
- Service Worker Life Cycle
- Hoe lang gaan Service Workers mee?
- Hoe controleer ik of een Service Worker geregistreerd is?
- Hoe maak ik een Service Worker ongeregistreerd
- Caching van Service Workers
- Hoe kan ik mijn Service Worker Cache updaten
- Welke Browsers ondersteunen Service Workers?
- Wat is het verschil tussen een Service Worker en een Web Worker
- Wat een Service Worker niet kan
Hoe werken Service Workers?
Een Service Worker zit tussen de browser en het netwerk, fungeert als een proxy server, en handelt een verzameling niet-UI-centrische taken af. Ze worden aangestuurd door gebeurtenissen en leven buiten het browserproces, waardoor ze kunnen werken zonder een actieve browsersessie. De service worker is een script dat wordt uitgevoerd in een thread, gescheiden van de UI. Hierdoor kan de service worker niet-UI-taken uitvoeren, waardoor een website beter presteert.
Service workers worden beëindigd wanneer ze niet worden gebruikt en hersteld wanneer dat nodig is, zodat ze de CPU niet belasten en batterijen leegmaken. Ze fungeren als een programmeerbare netwerkproxy, of tussenpersoon tussen de browser en het netwerk, waardoor ontwikkelaars zelf kunnen bepalen hoe netwerkverzoeken worden afgehandeld.
De eerste kracht die een servicewerker aan een website toevoegt, is de mogelijkheid om offline-mogelijkheden met granulaire controle mogelijk te maken. Dit wordt gedaan met een rijke caching API en het onderscheppen van alle netwerk verzoeken voordat ze vertrekken.
Caching maakt niet alleen offline ervaringen mogelijk, websites kunnen direct laden wanneer ze uit de cache worden opgehaald. Service worker caching maakt het netwerk een progressieve verbetering, of niet nodig om de site bruikbaar te maken.
Service Worker Extensibility
Een onderschatte service worker eigenschap is de uitbreidbaarheid Service workers zijn ontworpen om de ruggengraat te zijn die extra functionaliteit ondersteunt. De eerste twee functies die in browsers worden aangeboden zijn native push notifications en background sync. Meer nieuwe API’s worden momenteel besproken en zouden in de nabije toekomst in browsers moeten verschijnen.
Service workers leven in hun eigen thread en hebben geen toegang tot de DOM. Ze hebben ook hun eigen global scope, waarnaar wordt verwezen met behulp van de ‘self’ object.
De vereisen ook een site wordt geserveerd met behulp van HTTPS. Deze eis is te wijten aan de krachtige functies die service workers bieden. HTTPS voorkomt veel voorkomende aanvallen. Vandaag de dag moeten alle sites worden geserveerd met behulp van HTTPS als de belemmeringen voor de uitvoering zijn opgeheven en de minimale hoeveelheid veiligheid die zij bieden.
Ze zijn ook asynchroon. Dit betekent dat alle API’s promises ondersteunen. Dit betekent ook dat bepaalde API’s en functies niet toegankelijk zijn in service workers. De meest opvallende is localStorage. In plaats daarvan moeten gegevens worden opgeslagen met behulp van IndexedDB.
Service Worker Life Cycle
Voordat ontwikkelaars in deze geweldige service worker-functies duiken, moeten ze de levenscyclus begrijpen.
Een service worker moet worden geregistreerd door een website. Omdat sommige browsers nog geen service workers ondersteunen, moet u een functiecontrole uitvoeren voordat u een service worker registreert. Dit wordt gedaan door te controleren op de aanwezigheid van ‘serviceWorker’ in navigator.
if ('serviceWorker' in navigator) { navigator.serviceWorker.register('/sw.js') .then(function(registration) { // Registration was successful }) .catch(function(err) { // registration failed :( }); }
Om de service worker te registreren roep navigator.serviceWorker.register op. Geef het pad naar de service worker door. De register functie retourneert een belofte.
Als de belofte succesvol is, retourneert het een verwijzing naar het service worker registratie object. Van daaruit kunt u specifieke UI-taken naar behoefte uitvoeren.
Standaard Service Worker Events
- install
- activate
- fetch
- push (niet ondersteund door Safari)
- sync (nog niet ondersteund door de meeste browsers)
Wanneer een service worker is geregistreerd, wordt het “install”-gebeurtenis. In dit evenement de meest voorkomende taak uit te voeren heet pre-caching.
Pre-caching is waar een vooraf gedefinieerde lijst van activa bestanden die nodig zijn om een pagina of site te vormen, en voeg ze toe aan cache voordat ze worden aangevraagd. Dit maakt gebruik van de service worker cache om deze reacties te behouden.
self.addEventListener("install", event => { event.waitUntil( caches.open(preCacheName) .then(function (cache) { return cache.addAll(precache_urls); }) ); });
Het install event wordt slechts eenmaal in het leven van een service worker getriggerd. Het event treedt pas weer op als de service worker is bijgewerkt.
Het volgende event dat afgaat als onderdeel van de levenscyclus van de registratie is ‘activate’. Wanneer een service worker is geïnstalleerd, wordt deze niet onmiddellijk actief. De natuurlijke volgorde is dat een nieuwe service worker wacht tot alle service worker ‘clients’ zijn gesloten.
De reden dat service workers zijn ontworpen om niet onmiddellijk over te nemen, is om te voorkomen dat ze de gebruikerservaring verstoren.
De skipWaiting-functie dwingt een wachtende service worker om actief te worden. Deze functie mag alleen worden gebruikt als u er zeker van bent dat de nieuwe servicewerker geen bestaande clients kapotmaakt.
self.skipWaiting();
Als de servicewerker eenmaal actief wordt, vuurt het event ‘activate’.
self.addEventListener("activate", event => { //on activate event.waitUntil(clients.claim()); });
Dit event wordt meestal gebruikt om opruim- of migratietaken uit te voeren. Bijvoorbeeld het verwijderen van oude caches die in conflict kunnen komen met de nieuwe service worker caches.
Hoe lang gaan service workers mee?
Er is geen harde regel voor hoe lang een browser een service worker aan de gang houdt. Intern gebruikt de browser engine een aantal heuristieken om te bepalen wanneer het service worker proces moet worden beëindigd.
In het algemeen zal een slapende webpagina na een minuut of twee, misschien al na 30 seconden, worden afgesloten.
De werkelijkheid is dat de exacte tijd afhangt van de hardware, gebruikspatronen, etc.
Het goede nieuws is dat het maar een handvol milliseconden duurt om een service worker aan te zetten. Het is zo snel dat je niet echt een vertraging merkt. Je hoeft ook niets speciaals te programmeren om om te gaan met een scenario zonder de service worker, je site werkt gewoon. De magie van progressive enhancement.
Hoe controleer ik of een Service Worker is geregistreerd?
Er zijn meerdere manieren om te controleren of een Service Worker is geregistreerd. De eenvoudigste is om de serviceworkers.getRegistrations methode op te roepen.
navigator.serviceWorker.getRegistrations().then(registrations => { console.log(registrations); });
Dit is code die u kunt toevoegen aan uw pagina’s script om de registratie te loggen voor technische ondersteuning of ontwikkelaar debugging.
De ‘getRegistrations’ methode retourneert een array van alle serviceworkers geregistreerd onder de huidige scope of website.
Als u alleen de registratie naar de console wilt loggen, kunt u beter naar het tabblad Dev Tools ‘Application’ kijken. Het heeft een subpaneel dat een visuele weergave geeft van de geregistreerde service worker van de origin. U kunt ook activeren achtergrond synchronisatie evenementen en test push notifications.
U kunt ook de service worker verwijderen, forceer een update en ander algemeen beheer dat helpt bij development.
De echte waarde getRegistrations biedt is voor een soort van back-door support functie. We weten allemaal hoe het is om iemand op afstand te helpen en je hebt geen toegang tot DevTools om het probleem echt op te lossen. Soms wil je een soort visuele ondersteuningspagina of modal om informatie te geven over de applicatie status.
De gemiddelde consument zal niet weten hoe hij toegang moet krijgen tot het DevTools console paneel. In plaats daarvan kunt u een gebruikersinterface binnen de toepassing om de service worker registratie object eigenschappen echo.
Hoe kan ik een Service Worker
Hopefully u niet zult tegenkomen een scenario waar uw service worker code heeft een gebruikerservaring bug. In dat geval zijn er een paar dingen die u kunt doen om een service worker te verwijderen of te de-registreren.
De meeste scenario’s waarin u een service worker moet verwijderen, zullen zich voordoen tijdens het ontwikkelen van de applicatie. In dit geval kunt u de DevTools gebruiken om de service worker te verwijderen of af te melden.
Als je een uitgerolde service worker moet verwijderen, wordt het wat lastiger. Er zijn programmatische manieren om je uit de problemen te halen.
Lees meer over verwijderingstechnieken.
Service Worker Caching
De service worker specificatie bevat native caching mogelijkheden. Dit vervangt de traditionele appCache die sinds zijn ontstaan voor veel beheerproblemen heeft gezorgd. Service worker caching is veel beter te beheren.
De cache API biedt een persistentie laag die netwerk antwoorden opslaat die kunnen worden opgevraagd door het bijbehorende verzoek.
De sleutel tot het gebruik van service worker caching is de service worker ‘fetch’ event. Deze gebeurtenis triggers voor elk netwerk verzoek waardoor u het verzoek te onderscheppen en te controleren of het antwoord is gecached voordat het gaat naar het netwerk.
Door de toegang tot de activa in de lokale cache kunt u dure netwerk verzoeken te vermijden. Dit betekent dat de site kan werken wanneer er geen netwerk, offline, of een slechte netwerkverbinding, lage bars of valse cellulaire connectiviteit (bekend als LiFi).
self.addEventListener("fetch", event => { event.respondWith( fetchFromCache(event) .catch(() => fetch(request) .then(response => addToCache(cacheKey, request, response)) .catch(() => offlineResponse(resourceType, opts)) ) ); });
In het bovenstaande voorbeeld de code controleert of een reactie is eerder in de cache geplaatst. Zo ja, dan wordt het antwoord teruggestuurd. Zo niet, dan wordt het verzoek doorgegeven aan het netwerk.
Wanneer het verzoek terugkomt, wordt het antwoord in de cache opgeslagen en teruggegeven aan de UI.
Als het netwerk uitvalt, valt de logica terug op een offline-respons.
Er worden veel bewegende delen gebruikt in de voorbeeldcode. Ik zal meer details in een follow-up artikelen.
Hoe kan ik mijn Service Worker Cache
Een veel voorkomende misvatting is dat als je eenmaal een cache een netwerk verzoek wordt opgeslagen voor de eeuwigheid. Dit is niet het geval. U hebt volledige controle over wanneer en hoe de cache ongeldig wordt gemaakt en wordt bijgewerkt.
Dit is een zeer complex en betrokken onderwerp. Ik denk dat ik kan persoonlijk detail ongeveer 3 dozijn caching strategieën, alle betrekken een manier om cache ongeldig te beheren of het bijwerken van de cache.
Ik denk dat de sleutel tot ongeldig maken is het bepalen van ofwel een tijd om ongeldig te maken (time to live) waarde, een manifest of een achtergrond update proces. In het laatste geval kunt u een HEAD-verzoek doen om te zien of er een update op de server is uitgevoerd door de laatst bijgewerkte headerwaarde te vergelijken met de tijd dat het antwoord in de cache is opgenomen.
Er is geen eenduidig antwoord voor elke toepassing. U moet uw strategie plannen en bereid zijn om aan te passen als je ziet hoe uw toepassing wordt gebruikt.
Welke browsers ondersteunen Service Workers?
Alle moderne browsers ondersteunen service workers, op zijn minst caching. Chrome, FireFox en Edge ondersteunen native push notifications en Chrome en Edge hebben ondersteuning voor background sync.
Dit betekent dat de kern PWA functies beschikbaar zijn in alle apparaten en browsers. Push en background sync zijn uitbreidingen.
We hebben verschillende Progressive Web Apps gebouwd die geavanceerde offline caching strategieën vereisten om applicaties offline te laten werken, zelfs op iOS. Deze toepassingen vereisen alle verzoeken, zelfs POST, PUT en DELETE acties te worden gecached in een wachtrij. We hebben deze applicaties zelfs op iOS laten synchroniseren wanneer bekend was dat verbindingen beschikbaar waren.
Wat is het verschil tussen een Service Worker en een Web Worker
Service workers en web workers zijn vergelijkbare tools. Beide voeren processen uit in een aparte thread van de gebruikersinterface. Het echte verschil ligt in de feitelijke gebruikscontext.
Beiden hebben geen toegang tot het DOM of window object. Ze zijn beter voor middle tier of lange, procesintensieve taken.
Webworkers draaien alleen als een webpagina is geopend en een taak wordt getriggerd vanuit een script in de pagina.
Een service worker kan ook worden uitgevoerd als een pagina is geopend, maar kan ook worden getriggerd door een platform event zoals een push notification. Een webpagina hoeft niet open te zijn om een service worker te laten uitvoeren.
Service workers fungeren ook als proxy tussen het netwerk en de gebruikersinterface. Als een pagina wordt gebruikt (de meest voorkomende scenario) alle HTTPS-netwerk verzoeken passeren de service worker, zoals je geleerd in de caching sectie.
Communicatie tussen de UI en beide werkers wordt gedaan met behulp van de postMessage methode en het bericht evenement. Als je al eens multi-threaded hebt geprogrammeerd, is dit model heel bekend.
Wat een Service Worker niet kan doen
Service Workers hebben geen toegang tot het Window Object
Het window object wordt uitgevoerd in de UI thread, gescheiden van de service worker thread. Dit betekent dat een service worker niet direct DOM elementen kan manipuleren. De service worker en het venster kunnen communiceren via de postMessage methode. Dit maakt het mogelijk om berichten heen en weer te sturen. U zult aan elke kant logica moeten hebben om de berichten te verwerken en verschillende workflows te starten.
Service Workers vereisen HTTPS
Omdat Service Workers zoveel kracht hebben, worden ze alleen ingeschakeld als de pagina wordt geserveerd met HTTPS. Dit zorgt voor een niveau van beveiliging om de service worker in staat te stellen de dingen te doen waarvoor hij is ontworpen.
Over HTTP zou de service worker vatbaar zijn voor man in the middle aanvallen. Ontwikkelaars kunnen op localhost werken, waardoor we geen lokaal TLS-certificaat hoeven te installeren.
Met andere woorden, het antwoord op de vraag of een service worker op HTTP werkt, is nee. De site zal nog steeds renderen, maar de service worker registreert zich niet en wordt niet uitgevoerd.
Zijn alleen asynchroon
Service workers zijn asynchroon, wat betekent dat ze gebruik maken van en vertrouwen op Promises en API’s die Promises gebruiken. Dit betekent dat synchrone API’s zoals XHR en localStorage niet beschikbaar zijn voor een service worker. Vrees niet, je kunt de Fetch API (die XHR verving) en IndexedDB gebruiken. De meeste API’s die geen directe interactie hebben met het window object zijn toegankelijk in een service worker.