Provar du att ta reda på vad en serviceworker är? Du är inte ensam!

En Service Worker är ett skript som körs i bakgrunden, i en separat tråd från webbläsarens användargränssnitt. Service worker cache gör det möjligt för en webbplats att fungera offline. De är det tekniska kraftpaketet som nivåanpassar en webbplats till en progressiv webbapplikation. De möjliggör djup plattformsintegration, som rik caching, push-notiser och bakgrundssynkronisering.

Service workers är utformade för att vara en utbyggbar plattform, ytterligare funktioner planeras för närvarande.

De har inte tillgång till DOM, men kan avlyssna alla nätverksförfrågningar. Detta ger utvecklare möjlighet att styra hur förfrågningar hanteras, vilket ger ett rikt sätt att få webbplatser att fungera offline.

Service workers har kallats en game changer för webben. Jag tror inte att det är en enkel överdrift, eftersom de möjliggör många välbehövliga funktioner och gör kärnarkitekturen som jag använt i åratal infödd.

Service Workers låter fantastiskt!

Detta är nyckeltekniken eller det moderna webb-API som ligger bakom Progressive Web Applications. Utan en serviceworker är en webbplats bara en webbplats, lägg till en serviceworker och du har nu ett program.

Det finns några viktiga egenskaper hos service workers som du måste förstå:

  1. En Service Worker är en JavaScript-fil
  2. De körs på en separat tråd från användargränssnittet
  3. De kan inte få direkt åtkomst till DOM
  4. Det finns en livscykel eller en serie händelser som en Service Worker genomgår för att bli aktiv, vilket förklaras senare
  5. De är bara levande när de används, så inget batteri belastas
  6. De är isolerade till det ursprung eller den domän de är registrerade med
  7. Service Workers kräver HTTPS
  8. Kan skicka meddelanden till och från användargränssnittet
  9. Kräver inte en öppen webbsida för att fungera
  10. Stöds av alla större webbläsare, inklusive iOS Safari
  11. Liknande Web Workers, men bättre på många sätt
  • Hur fungerar Service Workers?
  • Service Worker Extensibility
  • Service Worker Life Cycle
  • Hur länge kan Service Workers pågå?
  • Hur kontrollerar jag om en Service Worker är registrerad?
  • Hur avregistrerar jag en tjänsteleverantör
  • Tjänsteleverantörens cache
  • Hur uppdaterar jag min tjänsteleverantörscache
  • Vilka webbläsare stöder tjänsteleverantörer?
  • Vad är skillnaden mellan en Service Worker och en Web Worker
  • Vad en Service Worker inte kan göra

Hur fungerar Service Workers?

En Service Worker sitter mellan webbläsaren och nätverket, fungerar som en proxyserver och hanterar en samling uppgifter som inte är inriktade på användargränssnittet. De är händelsestyrda och lever utanför webbläsarprocessen, vilket gör att de kan arbeta utan en aktiv webbläsarsession. Tjänstearbetaren är ett skript som körs i en tråd, separat från användargränssnittet. Detta gör det möjligt för tjänstearbetaren att utföra uppgifter utanför användargränssnittet, vilket gör att en webbplats presterar bättre.

Service Worker Diagram

Tjänstearbetarna avslutas när de inte används och återställs när det behövs, vilket gör att de inte belastar CPU:n och dränerar batterierna. De fungerar som en programmerbar nätverksproxy, eller mellanhand mellan webbläsaren och nätverket, vilket ger utvecklare möjlighet att utforma hur nätverksförfrågningar hanteras.

Den första kraften som en serviceworker ger en webbplats är möjligheten att aktivera offline-funktioner med granulär kontroll. Detta görs med ett rikt API för caching och genom att avlyssna alla nätverksförfrågningar innan de lämnar systemet.

Caching möjliggör inte bara offline-upplevelser, utan webbplatser kan laddas omedelbart när de hämtas från cacheminnet. Cachelagring av service workers gör nätverket till en progressiv förbättring eller krävs inte för att webbplatsen ska kunna användas.

Service Worker Extensibility

En underskattad funktion hos service workers är dess utbyggbarhet Service workers är utformade för att vara den ryggrad som stöder ytterligare funktionalitet. De två första funktionerna som levereras i webbläsare är inbyggda push-notiser och bakgrundssynkronisering. Fler nya API:er diskuteras för närvarande och bör börja dyka upp i webbläsare inom en snar framtid.

Service workers lever i en egen tråd och har inte tillgång till DOM. De har också en egen global räckvidd, som refereras till med hjälp av objektet ”self”.

De kräver också att en webbplats serveras med HTTPS. Detta krav beror på de kraftfulla funktioner som service workers erbjuder. HTTPS förhindrar många vanliga attacker. Idag bör alla webbplatser betjänas med HTTPS eftersom hindren för att implementera har lyfts och den minimala mängden säkerhet de erbjuder.

De är också asynkrona. Detta innebär att alla API:er har stöd för löften. Detta innebär också att vissa API:er och funktioner inte är tillgängliga i service workers. Den mest anmärkningsvärda är localStorage. Istället bör data lagras med hjälp av IndexedDB.

Service Worker Life Cycle

Service Worker Life Cycle

För att kunna dyka ner i dessa fantastiska serviceworker-funktioner måste utvecklare förstå livscykeln.

En serviceworker måste registreras av en webbplats. Eftersom vissa webbläsare fortfarande inte stöder service workers bör du utföra en funktionskontroll innan du registrerar en service worker. Detta görs genom att kontrollera om det finns ”serviceWorker” i navigator.

if ('serviceWorker' in navigator) { navigator.serviceWorker.register('/sw.js') .then(function(registration) { // Registration was successful }) .catch(function(err) { // registration failed :( }); } 

För att registrera servicearbetaren anropar du navigator.serviceWorker.register. Överlämna sökvägen till servicearbetaren. Funktionen register returnerar ett löfte.

Om det lyckas returnerar löftet en referens till registreringsobjektet för servicearbetaren. Därifrån kan du utföra specifika UI-uppgifter efter behov.

Standardhändelser för serviceworker

  1. installera
  2. aktivera
  3. fetch
  4. push (stöds inte av Safari)
  5. synkronisering (stöds inte av de flesta webbläsare ännu)

När en serviceworker är registrerad visas händelsen ”install”. I den här händelsen är den vanligaste uppgiften att utföra så kallad pre-caching.

Pre-caching är där en fördefinierad lista över tillgångsfiler som behövs för att bilda en sida eller webbplats, och lägga till dem i cacheminnet innan de begärs. Detta utnyttjar servicearbetarens cache för att bevara dessa svar.

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

Installationshändelsen utlöses endast en gång under en servicearbetares livstid. Händelsen utlöses inte igen förrän servicearbetaren uppdateras.

Nästa händelse som utlöses som en del av registreringens livscykel är ”activate”. När en tjänstemedarbetare installeras blir den inte omedelbart aktiv. Den naturliga sekvensen är att en ny servicearbetare väntar tills alla servicearbetares ”klienter” är stängda.

Anledningen till att servicearbetare är utformade så att de inte omedelbart tar över är för att förhindra att de bryter mot användarupplevelsen.

Funktionen skipWaiting tvingar en väntande servicearbetare att bli aktiv. Detta bör endast användas när du är säker på att den nya servicearbetaren inte kommer att bryta några befintliga klienter.

self.skipWaiting(); 
Arbetsflöde för uppdatering av servicearbetare

När servicearbetaren blir aktiv utlöses händelsen ”activate”.

self.addEventListener("activate", event => { //on activate event.waitUntil(clients.claim()); }); 

Denna händelse används vanligen för att utföra eventuella rensnings- eller migreringsuppgifter. Till exempel tar man bort gamla cacheminnen som kan vara i konflikt med de nya cacheminnena för servicearbetaren.

Hur länge ska servicearbetarna pågå?

Det finns ingen fast regel för hur länge en webbläsare ska hålla en servicearbetare igång. Internt använder webbläsarens motor en uppsättning heuristiker för att avgöra när tjänsten ska avslutas.

I allmänhet, om en webbsida är vilande, kommer processen att stängas av efter en minut eller två, kanske redan efter 30 sekunder.

I verkligheten beror den exakta tiden på maskinvara, användningsmönster osv.

Den goda nyheten är att det tar en handfull millisekunder att slå på en service worker. Det är så snabbt att du egentligen inte kommer att märka någon latens. Du behöver inte heller programmera något speciellt för att hantera ett scenario utan service worker, din webbplats kommer bara att fungera. Magin med progressiv förbättring.

Hur kontrollerar jag om en serviceworker är registrerad?

Det finns flera sätt att kontrollera om en serviceworker är registrerad. Det enklaste är att anropa metoden serviceworkers.getRegistrations.

 navigator.serviceWorker.getRegistrations().then(registrations => { console.log(registrations); });

Detta är kod som du kan lägga till i skriptet för dina sidor för att logga registreringen för teknisk support eller felsökning av utvecklare.

Metoden ”getRegistrations” returnerar en matris med alla tjänstemedarbetare som är registrerade under det aktuella tillämpningsområdet eller webbplatsen.

getRegistrations Registreringsobjekt

Om du bara loggar registreringen till konsolen är det bättre att titta på fliken ”Application” i Dev Tools. Den har en underpanel som visar en visuell bild av ursprungets registrerade servicearbetare. Du kan också utlösa synkroniseringshändelser i bakgrunden och testa push-meddelanden.

Du kan också ta bort servicearbetaren, tvinga fram en uppdatering och annan allmän hantering som underlättar utvecklingen.

Det verkliga värdet som getRegistrations erbjuder är för någon form av bakdörrssupportfunktion. Vi vet alla hur det är att försöka hjälpa någon på distans och du kan inte komma åt DevTools för att verkligen felsöka problemet. Ibland vill man ha någon form av visuell stödsida eller modal för att ge information om programtillståndet.

Den genomsnittlige konsumenten vet inte hur man får tillgång till DevTools konsolpanel. Istället kan du skapa ett användargränssnitt i programmet för att återge egenskaperna för registreringsobjektet för service workers.

Hur avregistrerar jag en service worker

Förhoppningsvis kommer du inte att stöta på ett scenario där din service worker-kod har skapat ett fel i användarupplevelsen. Om du gör det finns det några saker du kan göra för att ta bort eller avregistrera en service worker.

De flesta scenarier där du behöver ta bort en service worker är när du utvecklar applikationen. I det här fallet kan du använda DevTools för att ta bort eller radera servicearbetaren.

Om du behöver ta bort eller radera en distribuerad service worker blir det lite knepigare. Det finns programmatiska sätt att få dig ur knipan.

Läs mer om tekniker för borttagning.

Service Worker Caching

Specifikationen för Service Worker innehåller inbyggda cachingfunktioner. Detta ersätter den traditionella appCache som har orsakat många hanteringsproblem sedan den skapades. Cachelagring av service workers är mycket mer hanterbar.

Cache-API:et tillhandahåller ett persistensskikt som lagrar nätverkssvar som kan frågas ut av den matchande begäran.

Nyckeln till att använda caching av service workers är service worker ”fetch”-händelsen. Denna händelse utlöses för varje nätverksförfrågan så att du kan avlyssna förfrågan och kontrollera om svaret har cachelagrats innan det går till nätverket.

Du kan undvika dyra nätverksförfrågningar genom att få tillgång till tillgångar i den lokala cachen. Detta innebär att webbplatsen kan fungera när det inte finns något nätverk, när den är offline eller när nätverksanslutningen är dålig, när det finns låga staplar eller när det finns falska mobilanslutningar (LiFi).

self.addEventListener("fetch", event => { event.respondWith( fetchFromCache(event) .catch(() => fetch(request) .then(response => addToCache(cacheKey, request, response)) .catch(() => offlineResponse(resourceType, opts)) ) ); }); 

I exemplet ovan kontrollerar koden om ett svar tidigare har cachelagrats. Om så är fallet returneras det cachade svaret. Om inte skickas begäran vidare till nätverket.

Simple Service Worker Cache

När begäran återkommer cachas svaret och returneras till användargränssnittet.

Om nätverket misslyckas faller logiken tillbaka till ett offlinesvar.

Det är många rörliga delar som används i exempelkoden. Jag kommer att ge mer information i en uppföljande artikel.

Hur uppdaterar jag min Service Worker Cache

En vanlig missuppfattning är att när du cachelagrar en nätverksförfrågan lagras den för evigt. Detta är inte fallet. Du har fullständig kontroll över när och hur cachen ogiltigförklaras och uppdateras.

Det här är ett mycket komplext och involverat ämne. Jag tror att jag personligen kan redogöra för ungefär tre dussin cachingstrategier, alla involverar ett sätt att hantera cache-invalidering eller uppdatering av cacheminnet.

Jag tror att nyckeln till invalidering är att bestämma antingen ett värde för tid till invalidering (time to live), ett manifest eller en uppdateringsprocess i bakgrunden. I det senare fallet kan du göra en HEAD-förfrågan för att se om en uppdatering har gjorts på servern genom att jämföra det senast uppdaterade headervärdet med tiden då svaret cachas.

Det finns inget enkelt svar för varje tillämpning. Du måste planera din strategi och vara beredd att justera när du ser hur din applikation används.

Vilka webbläsare stöder service workers?

Alla moderna webbläsare stöder service workers, åtminstone caching. Chrome, FireFox och Edge har stöd för inbyggda push-notiser och Chrome och Edge har stöd för bakgrundssynkronisering.

Detta innebär att de centrala PWA-funktionerna är tillgängliga i alla enheter och webbläsare. Push och bakgrundssynkronisering är förbättringar.

Vi har byggt flera Progressive Web Apps som krävde sofistikerade strategier för caching offline för att programmen skulle fungera offline, även på iOS. Dessa applikationer kräver att alla förfrågningar, även POST-, PUT- och DELETE-åtgärder, cachas i en kö. Vi fick dessa applikationer att synka även på iOS när det var känt att anslutningar var tillgängliga.

Vad är skillnaden mellan en serviceworker och en webworker

Serviceworker och webworker är liknande verktyg. Båda utför processer i en separat tråd från användargränssnittet. Den verkliga skillnaden ligger i den faktiska användningskontexten.

Ingen av dem har tillgång till DOM- eller fönsterobjektet. De är bättre för mellanskiktet eller långa, processintensiva uppgifter.

Web workers körs endast när en webbsida är öppen och en uppgift utlöses från ett skript på sidan.

En service worker kan också exekveras när en sida är öppen, men kan också utlösas av en plattformshändelse som ett push-meddelande. En webbsida behöver inte vara öppen för att en tjänstearbetare ska kunna utföras.

Tjänstearbetare fungerar också som en proxy mellan nätverket och användargränssnittet. Om en sida används (det vanligaste scenariot) passerar alla HTTPS-nätverksförfrågningar genom servicearbetaren, vilket du lärde dig i avsnittet om cachelagring.

Kommunikationen mellan användargränssnittet och de båda arbetarna sker med hjälp av postMessage-metoden och meddelandehändelsen. Om du har gjort någon programmering med flera trådar är den här modellen mycket bekant.

Vad en serviceworker inte kan göra

Serviceworkerna kan inte komma åt Window-objektet

Fönsterobjektet exekveras i UI-tråden, separat från serviceworker-tråden. Detta innebär att en tjänstemedarbetare inte kan manipulera DOM-element direkt. Tjänstearbetaren och fönstret kan kommunicera via metoden postMessage. Detta gör det möjligt att skicka meddelanden fram och tillbaka. Du måste ha logik på varje sida för att bearbeta meddelandena och utlösa olika arbetsflöden.

Service Workers kräver HTTPS

Eftersom Service Workers har så mycket kraft aktiveras de endast om sidan serveras med HTTPS. Detta garanterar en säkerhetsnivå som gör det möjligt för serviceworker att göra de saker som den är utformad för att göra.

Med HTTP skulle servicearbetaren vara mottaglig för man in the middle-attacker. Utvecklare kan arbeta på localhost, vilket gör att vi inte behöver installera ett lokalt TLS-certifikat.

Med andra ord är svaret på frågan om en service worker fungerar på HTTP nej. Webbplatsen kommer fortfarande att renderas, men servicearbetaren registreras inte och exekveras inte.

Är endast asynkrona

Servicearbetare är asynkrona, vilket innebär att de använder och förlitar sig på Promises och API:er som använder Promises. Detta innebär att synkrona API:er som XHR och localStorage inte är tillgängliga för en service worker. Var inte rädd, du kan använda Fetch API (som ersatte XHR) och IndexedDB. De flesta API:er som inte interagerar direkt med fönsterobjektet är tillgängliga i en service worker.

Lämna ett svar

Din e-postadress kommer inte publiceras.