Stai cercando di capire cos’è un service worker? Non sei solo!

Un Service Worker è uno script che viene eseguito in background, in un thread separato dalla UI del browser. La cache dei service worker rende possibile il funzionamento offline di un sito web. Sono la centrale elettrica tecnica che eleva un sito web a un’applicazione web progressiva. Permettono una profonda integrazione della piattaforma, come il rich caching, le notifiche push e la sincronizzazione in background.

I service worker sono progettati per essere una piattaforma estensibile, ulteriori funzionalità sono attualmente in fase di pianificazione.

Non possono accedere al DOM, ma possono intercettare tutte le richieste di rete. Questo permette agli sviluppatori l’opportunità di controllare come vengono gestite le richieste, fornendo un modo ricco per far funzionare i siti web offline.

I service worker sono stati chiamati un game changer per il web. Non penso che sia una semplice esagerazione, perché abilitano molte capacità molto necessarie e rendono nativa l’architettura di base che ho usato per anni.

I service worker sembrano incredibili!

Questa è la tecnologia chiave o la moderna API web dietro le Progressive Web Applications. Senza un service worker un sito web è solo un sito web, aggiungi un service worker e ora hai un’applicazione.

Ci sono alcune caratteristiche chiave dei service worker che dovete capire:

  1. Un Service Worker è un file JavaScript
  2. Eseguono su un thread separato dall’UI
  3. Non possono accedere direttamente al DOM
  4. C’è un ciclo di vita o una serie di eventi che un service worker attraversa per diventare attivo, spiegato più avanti
  5. Sono attivi solo mentre vengono usati, quindi nessuna sollecitazione della batteria
  6. Sono isolati all’origine o al dominio con cui sono registrati
  7. I service worker richiedono HTTPS
  8. Possono inviare messaggi a e dall’UI
  9. Non richiedono una pagina web aperta per funzionare
  10. Sono supportati da tutti i principali browser, incluso iOS Safari
  11. Sono simili ai Web Workers, ma migliori in molti modi
  • Come funzionano i Service Workers?
  • Estensibilità dei service worker
  • Ciclo di vita dei service worker
  • Quanto dura un service worker?
  • Come faccio a controllare se un service worker è registrato?
  • Come faccio a disiscrivere un Service Worker
  • Service Worker Caching
  • Come faccio ad aggiornare la cache del mio Service Worker
  • Quali browser supportano i Service Worker?
  • Qual è la differenza tra un Service Worker e un Web Worker
  • Cosa non può fare un Service Worker

Come funzionano i Service Worker?

Un Service Worker si trova tra il browser e la rete, agendo come un server proxy, gestendo un insieme di compiti non incentrati sull’interfaccia utente. Sono guidati dagli eventi e vivono al di fuori del processo del browser, permettendo loro di lavorare senza una sessione attiva del browser. Il service worker è uno script che viene eseguito in un thread, separato dall’UI. Questo permette al service worker di eseguire compiti non-UI, rendendo un sito web più performante.

Diagramma del service worker

I service worker terminano quando non sono in uso e vengono ripristinati quando necessario, questo gli impedisce di sforzare la CPU e di scaricare le batterie. Agiscono come un proxy di rete programmabile, o intermediario tra il browser e la rete, permettendo agli sviluppatori di progettare come le richieste di rete sono gestite.

La prima potenza che un service worker porta ad un sito web è la capacità di abilitare capacità offline con controllo granulare. Questo viene fatto con una ricca API di caching e intercettando tutte le richieste di rete prima che partano.

Il caching non solo permette esperienze offline, i siti web possono caricarsi istantaneamente quando vengono recuperati dalla cache. Il caching dei service worker rende la rete un miglioramento progressivo, o non richiesto per rendere il sito utilizzabile.

Estensibilità del service worker

Una caratteristica sottovalutata del service worker è la sua estensibilità I service worker sono progettati per essere la spina dorsale che supporta funzionalità aggiuntive. Le prime due caratteristiche spedite nei browser sono le notifiche push native e la sincronizzazione in background. Altre nuove API sono attualmente in discussione e dovrebbero iniziare ad apparire nei browser nel prossimo futuro.

I service worker vivono in un proprio thread e non hanno accesso al DOM. Hanno anche un proprio ambito globale, a cui si fa riferimento usando l’oggetto ‘self’.

Richiedono anche che un sito sia servito usando HTTPS. Questo requisito è dovuto alle potenti caratteristiche che offrono i service worker. HTTPS previene molti attacchi comuni. Oggi tutti i siti dovrebbero essere serviti usando HTTPS poiché le barriere da implementare sono state eliminate e la quantità minima di sicurezza che offrono.

Sono anche asincroni. Questo significa che tutte le API supportano le promesse. Questo significa anche che alcune API e funzioni non sono accessibili nei service worker. La più notevole è localStorage. Invece, i dati dovrebbero essere memorizzati usando IndexedDB.

Ciclo di vita del service worker

Ciclo di vita del service worker

Prima di immergersi in queste grandi caratteristiche del service worker gli sviluppatori hanno bisogno di capire il ciclo di vita.

Un service worker deve essere registrato da un sito web. Poiché alcuni browser non supportano ancora i service worker, si dovrebbe eseguire un controllo delle caratteristiche prima di registrare un service worker. Questo viene fatto controllando la presenza di ‘serviceWorker’ in navigator.

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

Per registrare il service worker chiamate navigator.serviceWorker.register. Passa il percorso del service worker. La funzione register restituisce una promessa.

Se ha successo la promessa restituisce un riferimento all’oggetto di registrazione del lavoratore dei servizi. Da lì puoi eseguire compiti specifici dell’interfaccia utente come necessario.

Eventi standard del service worker

  1. installare
  2. attivare
  3. fetch
  4. push (non supportato da Safari)
  5. sync (non ancora supportato dalla maggior parte dei browser)

Quando un service worker viene registrato l’evento “install”. In questo evento il compito più comune da eseguire è chiamato pre-caching.

Pre-caching è dove un elenco predefinito di file di risorse necessarie per formare una pagina o un sito, e aggiungerli alla cache prima che vengano richiesti. Questo sfrutta la cache del service worker per persistere queste risposte.

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

L’evento install viene attivato solo una volta nella vita di un service worker. L’evento non si innescherà di nuovo finché il lavoratore dei servizi non sarà aggiornato.

Il prossimo evento che scatta come parte del ciclo di vita della registrazione è “activate”. Quando un service worker viene installato non diventa immediatamente attivo. La sequenza naturale è che un nuovo service worker aspetti fino a quando tutti i service worker ‘client’ sono chiusi.

Il motivo per cui i service worker sono progettati per non essere attivati immediatamente è per evitare che interrompano l’esperienza utente.

La funzione skipWaiting forza un service worker in attesa a diventare attivo. Questo dovrebbe essere impiegato solo quando sei sicuro che il nuovo service worker non romperà nessun client esistente.

self.skipWaiting(); 
Flusso di lavoro di aggiornamento del service worker

Una volta che il service worker diventa attivo, l’evento ‘activate’ scatta.

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

Questo evento è comunemente usato per eseguire qualsiasi compito di pulizia o migrazione. Per esempio, rimuovendo le cache legacy che potrebbero entrare in conflitto con le nuove cache dei service worker.

Quanto tempo durano i service worker?

Non c’è una regola fissa su quanto tempo un browser tenga in funzione un service worker. Internamente il motore del browser userà una serie di euristiche per determinare quando terminare il processo del service worker.

In generale se una pagina web è inattiva il processo si spegnerà dopo un minuto o due, forse già dopo 30 secondi.

La realtà è che il tempo esatto dipende dall’hardware, dai modelli di utilizzo, ecc.

La buona notizia è che ci vuole una manciata di millisecondi per accendere un service worker. È così veloce che non noterete alcuna latenza. Inoltre non hai bisogno di programmare nulla di speciale per affrontare uno scenario senza il service worker, il tuo sito funzionerà e basta. La magia del miglioramento progressivo.

Come faccio a controllare se un service worker è registrato?

Ci sono diversi modi per controllare se un service worker è registrato. Il più semplice è chiamare il metodo serviceworkers.getRegistrations.

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

Questo è il codice che puoi aggiungere allo script delle tue pagine per registrare la registrazione per il supporto tecnico o il debug degli sviluppatori.

Il metodo ‘getRegistrations’ restituisce un array di tutti i service worker registrati sotto lo scope o il sito web corrente.

getRegistrations Registration Object

Se stai solo registrando la registrazione nella console, sarebbe meglio visualizzare la scheda ‘Applicazione’ di Dev Tools. Ha un sotto-pannello che mostra una visuale del service worker registrato nell’origine. Puoi anche innescare eventi di sincronizzazione in background e testare le notifiche push.

Puoi anche cancellare il service worker, forzare un aggiornamento e altre gestioni generali che aiutano lo sviluppo.

Il vero valore che offre getRegistrations è per una sorta di funzionalità di supporto back-door. Sappiamo tutti com’è cercare di aiutare qualcuno da remoto e non si può accedere ai DevTools per risolvere realmente il problema. A volte vorrete una sorta di pagina di supporto visivo o modale per fornire informazioni sullo stato dell’applicazione.

Il consumatore medio non saprà come accedere al pannello della console di DevTools. Invece puoi creare un’interfaccia utente all’interno dell’applicazione per fare eco alle proprietà dell’oggetto di registrazione del service worker.

Come faccio a disiscrivere un service worker

Spero che non incontrerai uno scenario in cui il tuo codice service worker abbia creato un bug nell’esperienza utente. Nel caso lo facciate, ci sono alcune cose che potete fare per rimuovere o annullare la registrazione di un service worker.

La maggior parte degli scenari in cui avete bisogno di rimuovere un service worker sarà quando state sviluppando l’applicazione. In questo caso puoi usare i DevTools per rimuovere o cancellare il service worker.

Se hai bisogno di rimuovere o eliminare un service worker distribuito diventa un po’ più complicato. Ci sono modi programmatici per tirarti fuori dai guai.

Leggi di più sulle tecniche di rimozione.

Service Worker Caching

La specifica del service worker include capacità di caching native. Questo sostituisce la tradizionale appCache che ha causato molti problemi di gestione da quando è stata creata. La cache del lavoratore dei servizi è molto più gestibile.

L’API della cache fornisce uno strato di persistenza che memorizza le risposte della rete che possono essere interrogate dalla richiesta corrispondente.

La chiave per utilizzare la cache del lavoratore dei servizi è l’evento “fetch” del lavoratore dei servizi. Questo evento si innesca per ogni richiesta di rete, permettendoti di intercettare la richiesta e controllare se la risposta è stata messa in cache prima che vada in rete.

Accedendo alle risorse nella cache locale puoi rinunciare a costose richieste di rete. Questo significa che il sito può funzionare quando non c’è rete, offline, o scarsa connettività di rete, barre basse o falsa connettività cellulare (nota come LiFi).

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

Nell’esempio sopra il codice controlla se una risposta è stata precedentemente memorizzata nella cache. Se è così, viene restituita la risposta nella cache. Altrimenti la richiesta viene passata alla rete.

Simple Service Worker Cache

Quando la richiesta ritorna la risposta viene memorizzata nella cache e restituita all’interfaccia utente.

Se la rete fallisce la logica ritorna ad una risposta offline.

Ci sono molte parti mobili utilizzate nel codice di esempio. Fornirò maggiori dettagli in un articolo successivo.

Come faccio ad aggiornare la cache del mio Service Worker

Un malinteso comune è che una volta che si mette in cache una richiesta di rete questa viene memorizzata per l’eternità. Questo non è il caso. Hai il controllo completo su quando e come la cache viene invalidata e aggiornata.

Questo è un argomento molto complesso e coinvolto. Penso di poter dettagliare personalmente circa 3 dozzine di strategie di caching, tutte implicano un modo per gestire l’invalidazione della cache o l’aggiornamento della cache.

Penso che la chiave per l’invalidazione sia determinare o un valore di tempo per invalidare (time to live), un manifesto o un processo di aggiornamento in background. In quest’ultimo caso si può fare una richiesta HEAD per vedere se è stato fatto un aggiornamento sul server confrontando il valore dell’intestazione ultimo-aggiornato con il tempo della risposta nella cache.

Non c’è una risposta unica per ogni applicazione. Avrai bisogno di pianificare la tua strategia e di essere pronto ad aggiustare come vedi come viene usata la tua applicazione.

Quali browser supportano i service worker?

Tutti i browser moderni supportano i service worker, almeno la cache. Chrome, FireFox ed Edge supportano le notifiche push native e Chrome ed Edge hanno il supporto per la sincronizzazione in background.

Questo significa che le caratteristiche principali della PWA sono disponibili in tutti i dispositivi e browser. Push e background sync sono miglioramenti.

Abbiamo costruito diverse Progressive Web Apps che hanno richiesto sofisticate strategie di caching offline per consentire alle applicazioni di funzionare offline, anche su iOS. Queste applicazioni richiedono che tutte le richieste, anche le azioni POST, PUT e DELETE siano memorizzate nella cache in una coda. Abbiamo reso queste applicazioni sincronizzate anche su iOS quando le connessioni erano note per essere disponibili.

Qual è la differenza tra un Service Worker e un Web Worker

I service worker e i web worker sono strumenti simili. Entrambi eseguono processi in un thread separato dall’interfaccia utente. La vera differenza sta nel contesto d’uso effettivo.

Nessuno dei due ha accesso al DOM o all’oggetto finestra. Sono migliori per il middle tier o per compiti lunghi e intensivi di processo.

I web worker vengono eseguiti solo quando una pagina web è aperta e un compito è attivato da uno script nella pagina.

Un service worker può anche essere eseguito quando una pagina è aperta, ma può anche essere attivato da un evento della piattaforma come una notifica push. Una pagina web non deve essere aperta perché un service worker venga eseguito.

I service worker fungono anche da proxy tra la rete e l’interfaccia utente. Se viene utilizzata una pagina (lo scenario più comune) tutte le richieste di rete HTTPS passano attraverso il service worker, come hai imparato nella sezione caching.

La comunicazione tra l’UI ed entrambi i worker avviene utilizzando il metodo postMessage e l’evento message. Se hai fatto qualche programmazione multi-thread questo modello ti è molto familiare.

Cosa non può fare un service worker

I service worker non possono accedere all’oggetto Window

L’oggetto window viene eseguito nel thread dell’UI, separato dal thread del service worker. Questo significa che un service worker non può manipolare direttamente gli elementi DOM. Il service worker e la finestra possono comunicare attraverso il metodo postMessage. Questo permette ai messaggi di essere passati avanti e indietro. Avrete bisogno di una logica su ogni lato per elaborare i messaggi e innescare diversi flussi di lavoro.

I service worker richiedono HTTPS

Perché i service worker hanno così tanto potere, sono abilitati solo se la pagina è servita usando HTTPS. Questo assicura un livello di sicurezza che permette al service worker di fare le cose per cui è stato progettato.

Su HTTP il service worker sarebbe suscettibile di attacchi man in the middle. Gli sviluppatori possono lavorare su localhost, il che ci impedisce di installare un certificato TLS locale.

In altre parole la risposta a un service worker funziona su HTTP è no. Il sito renderà ancora, ma il service worker non si registra e non viene eseguito.

Sono solo asincroni

I service worker sono asincroni, il che significa che usano e si basano su Promises e API che usano Promises. Questo significa che le API sincrone come XHR e localStorage non sono disponibili per un service worker. Non temete, potete usare l’API Fetch (che ha sostituito XHR) e IndexedDB. La maggior parte delle API che non interagiscono direttamente con l’oggetto finestra sono accessibili in un service worker.

Lascia un commento

Il tuo indirizzo email non sarà pubblicato.