Questo codelab mostra come implementare un'esperienza di ricerca resiliente con Workbox. L'app demo che utilizza contiene una casella di ricerca che chiama un endpoint server e reindirizza l'utente a una pagina HTML di base.
Misura
Prima di aggiungere ottimizzazioni, è sempre buona prassi analizzare lo stato attuale dell'applicazione.
- Fai clic su Remixa per modificare per rendere il progetto modificabile.
- Per visualizzare l'anteprima del sito, premi Visualizza app. Quindi premi
Schermo intero
.
Nella nuova scheda appena aperta, controlla il comportamento del sito web quando è offline:
- Premi "Control+Maiusc+J" (o "Command+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 demo, inserisci una query di ricerca, quindi fai clic sul pulsante Cerca.
Viene visualizzata la pagina di errore standard del browser:
Fornire una risposta di riserva
Il service worker contiene il codice per aggiungere la pagina offline all'elenco della precache, in modo che possa essere sempre memorizzata nella cache all'evento install
del service worker.
In genere, devi indicare a Workbox di aggiungere questo file all'elenco della cache preliminare al momento della creazione, integrando la libreria con lo strumento di compilazione che preferisci (ad es. webpack o gulp).
Per semplicità, lo abbiamo già fatto noi per te. Il seguente codice in public/sw.js
esegue questa operazione:
const FALLBACK_HTML_URL = '/index_offline.html';
…
workbox.precaching.precacheAndRoute([FALLBACK_HTML_URL]);
Successivamente, aggiungi il codice per utilizzare la pagina offline come risposta di riserva:
- Per visualizzare l'origine, premi Visualizza origine.
- Aggiungi il seguente codice in fondo a
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 queste operazioni:
- Definisce una strategia Solo rete predefinita che verrà applicata a tutte le richieste.
- Dichiara un gestore di errori globale chiamando
workbox.routing.setCatchHandler()
per gestire le richieste non riuscite. Quando le richieste riguardano documenti, viene restituita una pagina HTML offline di riserva.
Per testare questa funzionalità:
- Torna all'altra scheda in cui è in esecuzione la tua app.
- Imposta di nuovo l'elenco a discesa Limitazione su Online.
- Premi il pulsante Indietro di Chrome per tornare alla pagina di ricerca.
- Assicurati che la casella di controllo Disattiva cache in DevTools sia deselezionata.
- Tieni premuto il pulsante Ricarica di Chrome e seleziona Svuota cache e ricarica forzata per assicurarti che il service worker venga aggiornato.
- Imposta di nuovo l'elenco a discesa Limitazione su Offline.
- Inserisci una query di ricerca e fai di nuovo clic sul pulsante Cerca.
Viene visualizzata la pagina HTML di riserva:
Richiedere 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 nella parte inferiore:
function requestNotificationPermission(event) {
event.preventDefault();
Notification.requestPermission().then(function (result) {
showOfflineText(result);
});
}
Il codice esegue queste operazioni:
- Quando l'utente fa clic su Abbonati alle 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
. - Trasmette l'autorizzazione risolta a
showOfflineText()
per mostrare il testo appropriato all'utente.
Mantenere le query offline e riprovare quando si torna online
Successivamente, implementa Workbox Background Sync per rendere persistenti le query offline, in modo che possano essere riprovate quando il browser rileva che la connettività è stata ripristinata.
- 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 queste 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 archiviate in IndexedDB.maxRetentionTime
indica il periodo di tempo in cui è possibile riprovare a inviare una richiesta. In questo caso abbiamo scelto 60 minuti (dopo i quali verrà eliminato).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 selezionata 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 trasmetti bgSyncPlugin
definito in precedenza. Aggiungi il seguente codice in fondo a 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],
}),
);
In questo modo, Workbox va sempre alla rete e, quando le richieste non vanno a buon fine, utilizza la logica di sincronizzazione in background.
Quindi, aggiungi il seguente codice in fondo a 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)
);
});
Testare la funzionalità
- Torna all'altra scheda in cui è in esecuzione la tua app.
- Imposta di nuovo l'elenco a discesa Limitazione su Online.
- Premi il pulsante Indietro di Chrome per tornare alla pagina di ricerca.
- Tieni premuto il pulsante Ricarica di Chrome e seleziona Svuota cache e ricarica forzata per assicurarti che il service worker venga aggiornato.
- Imposta di nuovo l'elenco a discesa Limitazione 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 a 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 Throttling (Limitazione) su Online.
Una volta ripristinata la connessione, verrà visualizzata una notifica:
Conclusione
Workbox offre 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 Workbox, per garantire che le query degli utenti offline non vengano perse e possano essere riprovate 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.