Questo codelab mostra come implementare un'esperienza di ricerca resiliente con Workbox. L'app di dimostrazione utilizzata contiene una casella di ricerca che chiama un endpoint del server e reindirizza l'utente a una pagina HTML di base.
Misura
Prima di aggiungere le ottimizzazioni, è sempre buona prassi analizzare lo stato attuale dell'applicazione.
- Fai clic su Remix per modificare per rendere il progetto modificabile.
- Per visualizzare l'anteprima del sito, premi Visualizza app, quindi premi A schermo intero .
Nella nuova scheda appena aperta, controlla il comportamento del sito web quando passa alla modalità offline:
- Premi "Control+Maiusc+J" (o "Comando+Opzione+J" su Mac) per aprire DevTools.
- Fai clic sulla scheda Rete.
- Apri Chrome DevTools e seleziona il riquadro Rete.
- Nell'elenco a discesa Limitazione, seleziona Offline.
- Nell'app di dimostrazione, inserisci una query di ricerca e fai clic sul pulsante Cerca.
Viene visualizzata la pagina di errore del browser standard:
Fornire una risposta di riserva
Il service worker contiene il codice per aggiungere la pagina offline all'elenco di precache, in modo che possa essere sempre memorizzata nella cache all'evento install
del service worker.
In genere, devi chiedere a Workbox di aggiungere questo file all'elenco di precache al momento della compilazione, integrando la libreria con lo strumento di compilazione che preferisci (ad es. webpack o gulp).
Per semplificare, abbiamo già fatto tutto noi. Il seguente codice in public/sw.js
esegue questa operazione:
const FALLBACK_HTML_URL = '/index_offline.html';
…
workbox.precaching.precacheAndRoute([FALLBACK_HTML_URL]);
Aggiungi il codice per utilizzare la pagina offline come risposta di riserva:
- Per visualizzare il codice sorgente, premi Visualizza sorgente.
- Aggiungi il seguente codice alla fine di
public/sw.js
:
workbox.routing.setDefaultHandler(new workbox.strategies.NetworkOnly());
workbox.routing.setCatchHandler(({event}) => {
switch (event.request.destination) {
case 'document':
return caches.match(FALLBACK_HTML_URL);
break;
default:
return Response.error();
}
});
Il codice esegue le seguenti operazioni:
- Definisce una strategia Solo rete predefinita che verrà applicata a tutte le richieste.
- Dichiara un gestore degli errori globale chiamando
workbox.routing.setCatchHandler()
per gestire le richieste non riuscite. Quando le richieste riguardano documenti, verrà restituita una pagina HTML offline di riserva.
Per testare questa funzionalità:
- Torna all'altra scheda in cui è in esecuzione la tua app.
- Ripristina l'impostazione Online nell'elenco a discesa Ritardo.
- Premi il pulsante Indietro di Chrome per tornare alla pagina di ricerca.
- Assicurati che la casella di controllo Disattiva cache in DevTools sia disattivata.
- Tieni premuto a lungo il pulsante Ricarica di Chrome e seleziona Svuota cache e ricarica forzata per assicurarti che il tuo worker di servizio sia aggiornato.
- Imposta di nuovo l'elenco a discesa Ritardo su Offline.
- Inserisci una query di ricerca e fai di nuovo clic sul pulsante Cerca.
Viene visualizzata la pagina HTML di riserva:
Richiedi l'autorizzazione alle notifiche
Per semplicità, la pagina offline all'indirizzo views/index_offline.html
contiene già il codice per richiedere le autorizzazioni di notifica in un blocco di script in basso:
function requestNotificationPermission(event) {
event.preventDefault();
Notification.requestPermission().then(function (result) {
showOfflineText(result);
});
}
Il codice esegue le seguenti operazioni:
- Quando l'utente fa clic su Iscriviti per ricevere notifiche, viene chiamata la funzione
requestNotificationPermission()
, che chiamaNotification.requestPermission()
per mostrare la richiesta di autorizzazione del browser predefinita. La promessa viene risolta con l'autorizzazione scelta dall'utente, che può esseregranted
,denied
odefault
. - Passa l'autorizzazione risolta a
showOfflineText()
per mostrare all'utente il testo appropriato.
Mantieni le query offline e riprova quando sei di nuovo online
Successivamente, implementa Workbox Background Sync per mantenere le query offline, in modo che possano essere riprovate quando il browser rileva che la connettività è tornata.
- Apri
public/sw.js
per la modifica. - Aggiungi il seguente codice alla fine del file:
const bgSyncPlugin = new workbox.backgroundSync.Plugin('offlineQueryQueue', {
maxRetentionTime: 60,
onSync: async ({queue}) => {
let entry;
while ((entry = await queue.shiftRequest())) {
try {
const response = await fetch(entry.request);
const cache = await caches.open('offline-search-responses');
const offlineUrl = `${entry.request.url}¬ification=true`;
cache.put(offlineUrl, response);
showNotification(offlineUrl);
} catch (error) {
await this.unshiftRequest(entry);
throw error;
}
}
},
});
Il codice esegue le seguenti operazioni:
workbox.backgroundSync.Plugin
contiene la logica per aggiungere le richieste non riuscite a una coda in modo che possano essere riprovate in un secondo momento. Queste richieste verranno mantenute in IndexedDB.maxRetentionTime
indica il periodo di tempo per cui è possibile riprovare a inviare una richiesta. In questo caso abbiamo scelto 60 minuti (dopodiché verranno eliminati).onSync
è la parte più importante di questo codice. Questo callback verrà chiamato quando la connessione sarà ripristinata in modo che le richieste in coda vengano recuperate e poi recuperate dalla rete.- La risposta di rete viene aggiunta alla cache
offline-search-responses
, aggiungendo il parametro di query¬ification=true
, in modo che questa voce della cache possa essere rilevata quando un utente fa clic sulla notifica.
Per integrare la sincronizzazione in background con il tuo servizio, definisci una strategia NetworkOnly per le richieste all'URL di ricerca (/search_action
) e passa il valore bgSyncPlugin
definito in precedenza. Aggiungi il seguente codice alla fine di public/sw.js
:
const matchSearchUrl = ({url}) => {
const notificationParam = url.searchParams.get('notification');
return url.pathname === '/search_action' && !(notificationParam === 'true');
};
workbox.routing.registerRoute(
matchSearchUrl,
new workbox.strategies.NetworkOnly({
plugins: [bgSyncPlugin],
}),
);
Questo indica a Workbox di accedere sempre alla rete e, quando le richieste non vanno a buon fine, di utilizzare la logica di sincronizzazione in background.
Aggiungi il seguente codice alla fine di public/sw.js
per definire una strategia di memorizzazione nella cache per le richieste provenienti dalle notifiche. Utilizza una strategia CacheFirst, in modo che possano essere pubblicati dalla cache.
const matchNotificationUrl = ({url}) => {
const notificationParam = url.searchParams.get('notification');
return (url.pathname === '/search_action' && (notificationParam === 'true'));
};
workbox.routing.registerRoute(matchNotificationUrl,
new workbox.strategies.CacheFirst({
cacheName: 'offline-search-responses',
})
);
Infine, aggiungi il codice per mostrare le notifiche:
function showNotification(notificationUrl) {
if (Notification.permission) {
self.registration.showNotification('Your search is ready!', {
body: 'Click to see you search result',
icon: '/img/workbox.jpg',
data: {
url: notificationUrl
}
});
}
}
self.addEventListener('notificationclick', function(event) {
event.notification.close();
event.waitUntil(
clients.openWindow(event.notification.data.url)
);
});
Testa la funzionalità
- Torna all'altra scheda in cui è in esecuzione la tua app.
- Ripristina l'impostazione Online nell'elenco a discesa Ritardo.
- Premi il pulsante Indietro di Chrome per tornare alla pagina di ricerca.
- Tieni premuto a lungo il pulsante Ricarica di Chrome e seleziona Svuota cache e ricarica forzata per assicurarti che il tuo worker di servizio sia aggiornato.
- Imposta di nuovo l'elenco a discesa Ritardo su Offline.
- Inserisci una query di ricerca e fai di nuovo clic sul pulsante Cerca.
- Fai clic su Iscriviti alle notifiche.
- Quando Chrome ti chiede se vuoi concedere all'app l'autorizzazione per inviare notifiche, fai clic su Consenti.
- Inserisci un'altra query di ricerca e fai di nuovo clic sul pulsante Cerca.
- Imposta di nuovo l'elenco a discesa Ritardo su Online.
Una volta ripristinata la connessione, viene visualizzata una notifica:
Conclusione
Workbox fornisce molte funzionalità integrate per rendere le tue PWA più resilienti e coinvolgenti. In questo codelab hai esplorato come implementare l'API Background Sync tramite l'astrazione di Workbox per assicurarti che le query degli utenti offline non vengano perse e che sia possibile riprovare una volta ripristinata la connessione. La demo è una semplice app di ricerca, ma puoi utilizzare un'implementazione simile per scenari e casi d'uso più complessi, tra cui app di chat, pubblicazione di messaggi su un social network e così via.