Cet atelier de programmation vous explique comment implémenter une expérience de recherche résiliente avec Workbox. L'application de démonstration qu'il utilise contient un champ de recherche qui appelle un point de terminaison du serveur et redirige l'utilisateur vers une page HTML de base.
Mesurer
Avant d'ajouter des optimisations, il est toujours judicieux d'analyser l'état actuel de l'application.
- Cliquez sur Remix to Edit (Remixer pour modifier) pour rendre le projet modifiable.
- Pour prévisualiser le site, appuyez sur Afficher l'application, puis sur Plein écran
.
Dans le nouvel onglet qui vient de s'ouvrir, vérifiez le comportement du site Web lorsqu'il est hors connexion :
- Appuyez sur Ctrl+Maj+J (ou Cmd+Option+J sur Mac) pour ouvrir les outils de développement.
- Cliquez sur l'onglet Réseau.
- Ouvrez les outils pour les développeurs Chrome et sélectionnez le panneau "Réseau".
- Dans la liste déroulante Throttling, sélectionnez Offline.
- Dans l'application de démonstration, saisissez une requête de recherche, puis cliquez sur le bouton Search (Rechercher).
La page d'erreur standard du navigateur s'affiche :
Fournir une réponse de remplacement
Le service worker contient le code permettant d'ajouter la page hors connexion à la liste de préchargement. Il peut donc toujours être mis en cache lors de l'événement install
du service worker.
En règle générale, vous devez demander à Workbox d'ajouter ce fichier à la liste du précache au moment de la compilation, en intégrant la bibliothèque à l'outil de compilation de votre choix (par exemple, webpack ou gulp).
Pour plus de simplicité, nous l'avons déjà fait pour vous. Le code suivant à public/sw.js
effectue cette opération :
const FALLBACK_HTML_URL = '/index_offline.html';
…
workbox.precaching.precacheAndRoute([FALLBACK_HTML_URL]);
Ajoutez ensuite du code pour utiliser la page hors connexion comme réponse de secours :
- Pour afficher la source, appuyez sur Afficher la source.
- Ajoutez le code suivant en bas de
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();
}
});
Le code :
- Définit une stratégie "Réseau uniquement" par défaut qui s'appliquera à toutes les demandes.
- Déclare un gestionnaire d'erreurs global en appelant
workbox.routing.setCatchHandler()
pour gérer les requêtes ayant échoué. Lorsque les requêtes concernent des documents, une page HTML hors connexion de secours est renvoyée.
Pour tester cette fonctionnalité :
- Revenez à l'autre onglet qui exécute votre application.
- Redéfinissez la liste déroulante Limitation du débit sur En ligne.
- Appuyez sur le bouton Retour de Chrome pour revenir à la page de recherche.
- Assurez-vous que la case à cocher Désactiver le cache dans les outils pour les développeurs est décochée.
- Appuyez de manière prolongée sur le bouton Actualiser de Chrome, puis sélectionnez Vider le cache et actualiser de force pour vous assurer que votre service worker est à jour.
- Redéfinissez la liste déroulante Limitation du débit sur Hors connexion.
- Saisissez une requête, puis cliquez de nouveau sur le bouton Rechercher.
La page HTML de remplacement s'affiche :
Demander une autorisation pour les notifications
Pour plus de simplicité, la page hors connexion à l'adresse views/index_offline.html
contient déjà le code permettant de demander les autorisations de notification dans un bloc de script en bas :
function requestNotificationPermission(event) {
event.preventDefault();
Notification.requestPermission().then(function (result) {
showOfflineText(result);
});
}
Le code :
- Lorsque l'utilisateur clique sur S'abonner aux notifications, la fonction
requestNotificationPermission()
est appelée, ce qui appelleNotification.requestPermission()
pour afficher l'invite d'autorisation du navigateur par défaut. La promesse est résolue avec l'autorisation choisie par l'utilisateur, qui peut êtregranted
,denied
oudefault
. - Transmet l'autorisation résolue à
showOfflineText()
pour afficher le texte approprié à l'utilisateur.
Conserver les requêtes hors connexion et réessayer lorsqu'elles sont de nouveau en ligne
Ensuite, implémentez Workbox Background Sync pour conserver les requêtes hors connexion. Elles pourront ainsi être relancées lorsque le navigateur détectera que la connectivité est rétablie.
- Ouvrez
public/sw.js
pour le modifier. - Ajoutez le code suivant à la fin du fichier :
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;
}
}
},
});
Le code :
workbox.backgroundSync.Plugin
contient la logique permettant d'ajouter les requêtes ayant échoué à une file d'attente afin qu'elles puissent être réessayées ultérieurement. Ces requêtes seront conservées dans IndexedDB.maxRetentionTime
indique la durée pendant laquelle une requête peut être relancée. Dans ce cas, nous avons choisi 60 minutes (après quoi, il sera supprimé).onSync
est la partie la plus importante de ce code. Ce rappel sera appelé lorsque la connexion sera rétablie afin que les requêtes mises en file d'attente soient récupérées, puis extraites du réseau.- La réponse du réseau est ajoutée au cache
offline-search-responses
, en ajoutant le paramètre de requête¬ification=true
, afin que cette entrée de cache puisse être récupérée lorsqu'un utilisateur clique sur la notification.
Pour intégrer la synchronisation en arrière-plan à votre service, définissez une stratégie NetworkOnly pour les requêtes envoyées à l'URL de recherche (/search_action
) et transmettez le bgSyncPlugin
défini précédemment. Ajoutez le code suivant en bas de 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],
}),
);
Cela indique à Workbox de toujours accéder au réseau et, en cas d'échec des requêtes, d'utiliser la logique de synchronisation en arrière-plan.
Ensuite, ajoutez le code suivant au bas de public/sw.js
pour définir une stratégie de mise en cache pour les requêtes provenant des notifications. Utilisez une stratégie CacheFirst pour qu'ils puissent être diffusés à partir du 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',
})
);
Enfin, ajoutez le code pour afficher les notifications :
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)
);
});
Tester la fonctionnalité
- Revenez à l'autre onglet qui exécute votre application.
- Redéfinissez la liste déroulante Limitation du débit sur En ligne.
- Appuyez sur le bouton Retour de Chrome pour revenir à la page de recherche.
- Appuyez de manière prolongée sur le bouton Actualiser de Chrome, puis sélectionnez Vider le cache et actualiser de force pour vous assurer que votre service worker est à jour.
- Redéfinissez la liste déroulante Limitation du débit sur Hors connexion.
- Saisissez une requête, puis cliquez de nouveau sur le bouton Rechercher.
- Cliquez sur S'abonner aux notifications.
- Lorsque Chrome vous demande si vous souhaitez autoriser l'application à envoyer des notifications, cliquez sur Autoriser.
- Saisissez une autre requête, puis cliquez de nouveau sur le bouton Rechercher.
- Redéfinissez la liste déroulante Limitation du débit sur En ligne.
Une fois la connexion rétablie, une notification s'affiche :
Conclusion
Workbox fournit de nombreuses fonctionnalités intégrées pour rendre vos PWA plus résilientes et attrayantes. Dans cet atelier de programmation, vous avez appris à implémenter l'API Background Sync à l'aide de l'abstraction Workbox, afin de vous assurer que les requêtes utilisateur hors connexion ne sont pas perdues et peuvent être retentées une fois la connexion rétablie. La démo est une application de recherche simple, mais vous pouvez utiliser une implémentation similaire pour des scénarios et des cas d'utilisation plus complexes, y compris les applications de chat, la publication de messages sur un réseau social, etc.