J'utilise Lighthouse pour auditer ma webapp. Je travaille sur les échecs, mais je suis coincé sur celui-ci:
Échecs: le manifeste start_url n'est pas mis en cache par un technicien de service.
Dans mon manifest.json
J'ai
"start_url": "index.html",
Dans mon worker.js
, Je mets en cache les éléments suivants:
let CACHE_NAME = 'my-site-cache-v1';
let urlsToCache = [
'/',
'/scripts/app.js',
'/index.html'
];
Qui correspond à ce que je vois dans l'onglet Application de Chrome Dev tools:
Alors ... pourquoi me dit-il que start_url
N'est pas mis en cache?
Voici mon fichier worker.js
Complet:
if ('serviceWorker' in navigator) {
window.addEventListener('load', function() {
navigator.serviceWorker.register('/worker.js').then(function(registration) {
console.log('ServiceWorker registration successful with scope: ', registration.scope);
}, function(err) {
console.log('ServiceWorker registration failed: ', err);
});
});
}
let CACHE_NAME = 'my-site-cache-v1.1';
let urlsToCache = [
'/',
'/scripts/app.js',
'/index.html'
];
self.addEventListener('install', function(event) {
event.waitUntil(
caches.open(CACHE_NAME)
.then(function(cache) {
console.log('Opened cache');
return cache.addAll(urlsToCache);
})
);
});
Regardons le phare de code source
static assessOfflineStartUrl(artifacts, result) {
const hasOfflineStartUrl = artifacts.StartUrl.statusCode === 200;
if (!hasOfflineStartUrl) {
result.failures.Push('Manifest start_url is not cached by a service worker');
}
}
Nous pouvons remarquer que ce n'est pas la vérification de votre cache, mais la réponse du point d'entrée . Cela doit être dû au fait que votre technicien n'envoie pas de réponse appropriée lors de la récupération.
Vous saurez que cela fonctionne, si dans DevTools, dans votre première demande, il y aura (de ServiceWorker) dans la colonne de taille:
Il y a deux problèmes avec le code que vous avez fourni:
Le premier est que vous vous trompez travailleur de service code avec enregistrement de travailleur de service code. Le code d'enregistrement du technicien doit être le code exécuté sur votre page Web.
Ce code devrait être inclus sur votre page:
if ('serviceWorker' in navigator) {
window.addEventListener('load', function() {
navigator.serviceWorker.register('/worker.js').then(function(registration) {
console.log('ServiceWorker registration successful with scope: ', registration.scope);
}, function(err) {
console.log('ServiceWorker registration failed: ', err);
});
});
}
et le reste de ce que vous avez collé devrait être votre code worker.js. Cependant, le service worker est installé, car vous avez des fichiers dans le cache, donc je soupçonne que vous venez de coller cela de manière incorrecte.
Le deuxième (vrai) problème est que le service worker ne renvoie pas ces fichiers mis en cache. Comme je l'ai prouvé plus tôt, cette erreur de phare signifie que le technicien ne retourne pas start_url
fichier d'entrée.
Le code le plus basique pour y parvenir est:
self.addEventListener('fetch', function(event) {
event.respondWith(caches.match(event.request));
});
Le technicien de service est piloté par les événements. Par conséquent, lorsque votre page souhaite obtenir des ressources, le technicien de service réagit et sert celle du cache. Dans le monde réel, vous ne voulez vraiment pas l'utiliser comme ça, car vous avez besoin d'une sorte de secours. Je recommande fortement de lire la section Servir des fichiers depuis le cache ici
Edit : J'ai créé pull request dans le code source de Lighthouse pour clarifier ce message d'erreur
Il semble que Chrome lighthouse (chrome v62) exécute une fetch()
générique. Voir la discussion sur https://github.com/GoogleChrome/lighthouse/ issues/2688 # issuecomment-315394447
Dans mon cas, un fichier offline.html est diffusé après un "if (event.request.mode === 'navigate'){
". En raison de l'utilisation de la fonction générique fetch()
de lighthouse, lighthouse ne sera pas servi ce offline.html, et affiche l'erreur "Manifest start_url n'est pas mis en cache par un Service Worker".
J'ai résolu ce problème en remplaçant:
if (event.request.mode === 'navigate'){
avec
if (event.request.method === 'GET' ){