Registrazione dei service worker

Best practice per la scelta del momento della registrazione del service worker.

I service worker possono velocizzare in modo significativo le visite ripetute alla tua app web, ma devi adottare misure per assicurarti che l'installazione iniziale di un service worker non peggiori l'esperienza di prima visita dell'utente.

In genere, posticipare la registrazione del service worker fino al caricamento della pagina iniziale offre la migliore esperienza agli utenti, in particolare a quelli che utilizzano dispositivi mobili con connessioni di rete più lente.

Boilerplate di registrazione comune

Se hai mai letto qualcosa sui worker di servizio, probabilmente hai trovato del codice boilerplate sostanzialmente simile al seguente:

if ('serviceWorker' in navigator) {
    navigator.serviceWorker.register('/service-worker.js');
}

A volte, questo messaggio potrebbe essere accompagnato da alcune istruzioni console.log() o da codice che rileva un aggiornamento di una registrazione di service worker precedente, per informare gli utenti di aggiornare la pagina. Tuttavia, si tratta solo di piccole variazioni rispetto alle poche righe di codice standard.

Quindi, ci sono sfumature per navigator.serviceWorker.register? Esistono delle best practice da seguire? Non sorprende (dato che questo articolo non termina qui), la risposta a entrambe è "sì".

La prima visita di un utente

Prendiamo in considerazione la prima visita di un utente a un'app web. Non è ancora presente un servizio worker e il browser non ha modo di sapere in anticipo se verrà eventualmente installato un servizio worker.

In qualità di sviluppatore, la tua priorità dovrebbe essere assicurarti che il browser riceva rapidamente l'insieme minimo di risorse fondamentali necessarie per visualizzare una pagina interattiva. Qualsiasi elemento che rallenti il recupero di queste risposte è nemico di un'esperienza interattiva rapida.

Ora immagina che durante il download del codice JavaScript o delle immagini necessarie per il rendering della pagina, il browser decida di avviare un thread o un processo in background (per brevità, assumeremo che si tratti di un thread). Supponiamo che non utilizzi un computer desktop potente, ma il tipo di cellulare sottodimensionato che gran parte del mondo considera il proprio dispositivo principale. L'avvio di questo thread aggiuntivo aggiunge contese per il tempo della CPU e la memoria che il browser potrebbe altrimenti spendere per il rendering di una pagina web interattiva.

È improbabile che un thread in background inattivo faccia una differenza significativa. Ma cosa succede se il thread non è inattivo, ma decide di iniziare anche a scaricare risorse dalla rete? Qualsiasi dubbio sulla contesa della CPU o della memoria dovrebbe essere superato dalle preoccupazioni relative alla larghezza di banda limitata disponibile su molti dispositivi mobili. La larghezza di banda è preziosa, quindi non minare le risorse critiche scaricando contemporaneamente risorse secondarie.

Tutto ciò significa che l'avvio di un nuovo thread di worker di servizio per scaricare e memorizzare nella cache le risorse in background può andare contro il tuo obiettivo di fornire l'esperienza più breve possibile la prima volta che un utente visita il tuo sito.

Migliorare il testo standard

La soluzione è controllare l'avvio del service worker scegliendo quando chiamare navigator.serviceWorker.register(). Una semplice regola empirica consiste nel ritardare la registrazione fino a dopo l'attivazione di load event il giorno window, come segue:

if ('serviceWorker' in navigator) {
    window.addEventListener('load', function() {
    navigator.serviceWorker.register('/service-worker.js');
    });
}

Tuttavia, il momento giusto per avviare la registrazione del servizio worker può dipendere anche da cosa fa la tua app web subito dopo il caricamento. Ad esempio, l'app web Google I/O 2016 presenta una breve animazione prima della transizione alla schermata principale. Il nostro team ha rilevato che l'avvio della registrazione del servizio worker durante l'animazione potrebbe causare problemi su dispositivi mobili di fascia bassa. Anziché offrire agli utenti un'esperienza negativa, abbiamo ritardo la registrazione del servizio worker fino al termine dell'animazione, quando il browser aveva maggiori probabilità di avere alcuni secondi di inattività.

Analogamente, se la tua app web utilizza un framework che esegue una configurazione aggiuntiva dopo il caricamento della pagina, cerca un evento specifico del framework che segnali quando l'operazione è completata.

Visite successive

Finora ci siamo concentrati sull'esperienza della prima visita, ma che impatto ha la registrazione ritardata dei worker di servizio sulle visite ripetute al tuo sito? Anche se potrebbe sorprendere alcune persone, non dovrebbe esserci alcun impatto.

Quando un service worker viene registrato, passa attraverso gli eventi di ciclo di vita install e activate. Una volta attivato, un service worker può gestire gli eventi fetch per tutte le visite successive alla tua app web. Il service worker si avvia prima della richiesta di qualsiasi pagina nel suo ambito, il che è logico. Se il service worker esistente non fosse già in esecuzione prima di visitare una pagina, non avrebbe la possibilità di soddisfare gli eventi fetch per le richieste di navigazione.

Pertanto, una volta che è presente un worker di servizio attivo, non importa quando chiami navigator.serviceWorker.register() o, in effetti, se lo chiami. A meno che non modifichi l'URL dello script del worker di servizio, navigator.serviceWorker.register() è effettivamente un comando senza esecuzione durante le visite successive. Il momento in cui viene chiamato non è rilevante.

Motivi per registrarsi in anticipo

Esistono scenari in cui ha senso registrare il tuo worker di servizio il prima possibile? Un esempio è quando il tuo worker dei servizi utilizza clients.claim() per assumere il controllo della pagina durante la prima visita e il worker dei servizi esegue in modo aggressivo la memorizzazione nella cache di runtime all'interno del suo gestore fetch. In questa situazione, è utile attivare il servizio worker il più rapidamente possibile per provare a compilare le relative cache di runtime con risorse che potrebbero essere utili in un secondo momento. Se la tua app web rientra in questa categoria, vale la pena fare un passo indietro per assicurarti che l'handler install del tuo service worker non richieda risorse che competono per la larghezza di banda con le richieste della pagina principale.

Provare

Un ottimo modo per simulare una prima visita è aprire l'app web in una finestra di Chrome in incognito e controllare il traffico di rete in Chrome DevTools. In qualità di sviluppatore web, probabilmente ricarichi un'istanza locale della tua app web decine e decine di volte al giorno. Tuttavia, se visiti di nuovo il tuo sito quando è già presente un servizio worker e le cache sono completamente compilate, non avrai la stessa esperienza di un nuovo utente ed è facile ignorare un potenziale problema.

Ecco un esempio che illustra la differenza che può fare il momento della registrazione. Entrambi gli screenshot sono stati acquisiti durante la visita a un'app di esempio in modalità di navigazione in incognito utilizzando la limitazione della rete per simulare una connessione lenta.

Traffico di rete con registrazione anticipata.

Lo screenshot sopra riflette il traffico di rete quando il sample è stato modificato per eseguire la registrazione del service worker il prima possibile. Puoi vedere le richieste di precaching (le voci con l'icona a forma di ingranaggio accanto, originate dall'handler install del service worker) alternate alle richieste per le altre risorse necessarie per visualizzare la pagina.

Traffico di rete con registrazione tardiva.

Nello screenshot riportato sopra, la registrazione del service worker è stata ritardata fino al caricamento della pagina. Puoi notare che le richieste di precaching non iniziano finché tutte le risorse non sono state recuperate dalla rete, eliminando qualsiasi contesa per la larghezza di banda. Inoltre, poiché alcuni degli elementi che stiamo precaricando sono già nella cache HTTP del browser (gli elementi con (from disk cache) nella colonna Dimensioni), possiamo compilare la cache del service worker senza dover accedere di nuovo alla rete.

Punti extra se esegui questo tipo di test da un dispositivo di fascia bassa reale su una rete mobile reale. Puoi sfruttare le funzionalità di debugging remoto di Chrome per collegare uno smartphone Android al tuo computer tramite USB e assicurarti che i test che stai eseguendo riflettano effettivamente l'esperienza reale di molti dei tuoi utenti.

Conclusione

In sintesi, assicurarti che i tuoi utenti abbiano la migliore esperienza possibile alla prima visita dovrebbe essere una priorità assoluta. Ritardare la registrazione del service worker fino al caricamento della pagina durante la visita iniziale può contribuire a garantire questo risultato. Continuerai a usufruire di tutti i vantaggi di un servizio worker per le tue visite ripetute.

Un modo semplice per ritardare la registrazione iniziale del tuo service worker fino al caricamento della prima pagina è utilizzare quanto segue:

if ('serviceWorker' in navigator) {
    window.addEventListener('load', function() {
    navigator.serviceWorker.register('/service-worker.js');
    });
}