Dans notre précédent article, nous avons vu ce qu’est une Progressive Web App (PWA) et l’usage qui en est fait ces dernières années. Nous avions aussi évoqué les 3 composants qui permettent d’identifier une application web comme une PWA. Pour rappel :

  1. 🔒 Une connexion à l’application en HTTPS, c’est même un prérequis ;
  2. 📄 Un web manifest contenant des informations sur l’application (nom, icône, mode d’affichage…) ;
  3. ⚙Un service worker, qui est l’élément clé des PWA. Il permet notamment de gérer le mode offline et la mauvaise connexion du device en utilisant le cache du navigateur, la synchronisation des données et la réception des notifications push.

https manifest service worker

Je vous propose aujourd’hui, à partir d’une application web existante, de vous montrer comment ajouter ces différentes briques pour que votre application devienne une PWA.

 

Transformer votre application web en application PWA

💡 Si vous utilisez des Frameworks ou des librairies JavaScript, n’hésitez pas à regarder si un module PWA existe au préalable. Par exemple, pour Angular, le package @angular/pwa est bien documenté. Il permet notamment de versionner automatiquement votre service worker lors des builds de votre projet et de gérer plus facilement le cache de votre application PWA (mise en place d’une stratégie de mise en cache, identification par les noms ou les types des fichiers à mettre en cache…).

 

HTTPS

Tout d’abord, votre application web doit être accessible en HTTPS. C’est un prérequis pour que le service worker fonctionne correctement. Si jamais un utilisateur accède à votre site en HTTP, il doit être automatiquement redirigé en HTTPS.

De plus, dans le cas d’une application web publique, Google classe mieux les sites en HTTPS dans son moteur de recherche.

 

Web Manifest

Le fichier webmanifest est un fichier JSON qui décrit les métadonnées de la PWA. Il contient les indications sur la façon dont l’application doit être installée (nom, icône de raccourci) et comment elle doit s’afficher (orientation, affichage en mode plein écran…).

Dans votre projet web, il suffit de créer un fichier avec l’extension .webmanifest.

Voici un exemple de fichier web manifest :

{

  "name": "PWA Demo - Custom News Reader",

  "short_name": "PWA demo",

  "theme_color": "#5A0FC8",

  "background_color": "#fafafa",

  "display": "standalone",

  "scope": "/",

  "start_url": "/",

  "icons": [

    {

      "src": "assets/icons/android-chrome-192x192.png",

      "sizes": "192x192",

      "type": "image/png"

    },

    {

      "src": "assets/icons/android-chrome-512x512.png",

      "sizes": "512x512",

      "type": "image/png"

    }

  ]

}

 

Dans cet exemple, vous trouverez l’essentiel des valeurs à renseigner :

  • name : nom de l’application.
  • short_name : nom court de l’application. Il sera utilisé notamment sur l’écran d’accueil (nom de l’application sous l’icône).
  • theme_color : couleur de la barre d’adresse si elle est visible.
  • background_color : couleur de fond. On la voit notamment au lancement de la PWA.
  • display : permet d’indiquer le mode d’affichage de l’application. Il y a 4 valeurs possibles :
    • fullscreen: ouverture de l’application PWA en plein écran ;
    • standalone: on ne garde que la status bar et parfois les boutons systèmes (boutons en bas de l’écran) ;
    • minimal-ui: proche de browser sauf qu’il n’est pas possible de changer l’url ;
    • browser : s’ouvre dans un nouvel onglet ou une nouvelle fenêtre.

 

Exemple avec un téléphone Android :

Android affichage map PWA

  • scope : permet de définir le scope de navigation du contexte applicatif. Si une url est en dehors de ce scope (ex : lien externe), l’url s’ouvre dans une nouvelle fenêtre.
  • start_url : url au démarrage de l’application.
  • icons : liste des différentes tailles d’icônes de l’application. Elles seront utilisées pour l’installation de l’application (raccourci sur l’écran d’accueil par exemple), lors du lancement de l’application, etc. Il faudra donc créer une icône et la décliner en plusieurs tailles. Vous pouvez vous aider du site realfavicon.

Si vous voulez en savoir plus, vous pouvez consulter le site de la W3C.

 

Exemple d’écran d’accueil (ou « Splash screen ») d’une application PWA :

  • theme_color
  • Icon
  • Background-color
  • Name

Ecran d'accueil - splash screen - d'une application PWA

Une fois le fichier webmanifest créé, vous devez le référencer dans le header de votre fichier index.html.

<link rel="manifest" href="/manifest.webmanifest">

 

Service Worker

Un Service Worker est un type de web worker. Dans un fichier JavaScript, on définit un ensemble d’instructions qui sera exécuté dans un thread en arrière-plan, indépendant du thread de l’application web. Le service worker n’a donc pas accès au DOM et aucune interaction n’est possible directement avec l’utilisateur.

Il peut être vu comme un proxy entre l’application et le réseau : il intercepte toutes les requêtes et applique la stratégie de mise en cache souhaitée. Par exemple, si on applique la stratégie du « cache first » (ou « offline first »), on vérifie si la ressource existe déjà en cache avant d’aller la chercher sur le réseau.

SErvice worker fonctionnement schéma

Le Service Worker permet également :

  • La gestion du mode offline en vérifiant le statut du réseau ;
  • La réception de notifications push (API Push) ;
  • De lancer des synchronisations en arrière-plan (non supportées sur Firefox) ;
  • De vérifier s’il y a une mise à jour de l’application…

Déclaration du Service Worker

Au niveau de votre application web, il faut enregistrer votre Service Worker en renseignant le chemin

// Register our service worker
if ('serviceWorker' in navigator) { // check browser compatability
    navigator.serviceWorker.register('/sw.js') // register your service worker file
        .then((reg) => { // success
            console.log('Service worker registered! Scope : ' + reg.scope);
        })
        .catch((err) => { // failure
            console.log('Registration failed! ' + err);
        });
} else {
    console.log('The browser does not support Service Worker');
}

Installation et mise en route du Service Worker

Une fois le Service Worker enregistré, les principaux événements sont install et activate.

⚠ Attention, le Service Worker est prêt uniquement lorsqu’il est au statut activated.

Installation du service worker PWA

L’étape install permet, par exemple, de mettre en cache les éléments statiques de votre application (ex : images, icônes, scripts, css, polices…), pour la gestion du mode offline ou pour mettre à jour le code du Service Worker.

 

const CACHE_NAME = 'pwa-cache-v1'; // cache name and version number (update version number for each update)
const CONTENT_TO_CACHE = [
    '/',
    '/index.html',
    '/scripts/app.js',
    '/styles/styles.css',
    '/assets/icons/android-chrome-192x192.png',
    '/assets/icons/android-chrome-512x512.png',
    '/assets/icons/apple-touch-icon.png',
    '/assets/icons/favicon-16x16.png',
    '/assets/icons/favicon-32x32.png',
    '/assets/icons/mstile-150x150.png',
    '/assets/icons/safari-pinned-tab.svg'
];

// Install event
self.addEventListener('install', function (e) {
    console.log('Service Worker -- Install');

    e.waitUntil(
        caches.open(cacheName).then(function (cache) {
            console.log('Service Worker -- Caching all: app shell and content');
            return cache.addAll(contentToCache);
        })
    );
});

 

Mise en cache

L’événement fetch permet de suivre toutes les requêtes HTTP faites par votre application. On peut, par exemple, filtrer par url ou par type de ressources, afin de choisir la stratégie de cache qu’on souhaite mettre en place.

Ici, pour chaque requête, on vérifie si l’élément est déjà en cache, si ce n’est pas le cas, on lance une requête pour récupérer le contenu et le mettre en cache.

 

// Fetching content using Service Worker
self.addEventListener('fetch', function(e) {
e.respondWith(
        caches.match(e.request).then(function (response) {
            if (response) {
                console.debug('Service Worker -- Get data from cache: ' + e.request.url);
                return response;
            }

            return fetch(e.request).then(function (response) {
                return caches.open(CACHE_NAME).then(function (cache) {
                    console.debug('Service Worker -- Fetch and caching new resource: ' + e.request.url);
                    cache.put(e.request, response.clone());
                    return response;
                });
            });
        })
    );
});


Tester votre site en PWA

Dans l’article précédent, nous avons abordé la compatibilité des PWA avec les navigateurs web modernes.

Pour tester votre application en mode PWA, je vous conseille d’utiliser Chrome ou une version récente de Microsoft Edge. Firefox peut aussi faire l’affaire.

Avec Chrome ou Microsoft Edge (>= version 79), lorsque vous lancez votre application en mode debug, ouvrez votre débuggeur sur l’onglet Application. Vous pouvez voir le nom et le statut de votre Service Worker.

 

PWA service worker debug

Sur la partie de gauche, d’autres catégories pourraient vous intéresser :

  • Manifest pour vérifier que le navigateur a bien détecté votre fichier web manifest, et avoir un aperçu de votre fichier vu par le navigateur ;
  • Cache Storage pour vérifier ce qui est mis en cache.

 

PWA cache debug

Pour continuer vos tests sur votre application web en mode PWA, vous pouvez débuguer à partir d’un smartphone ou d’une tablette, en déployant votre application :

  • Localement sur votre ordinateur ;
  • Sur un serveur web.

Vous pourrez ainsi voir dans l’onglet Network tout ce qui vient du cache (Mention ServiceWorker dans l’onglet Size) :

PWA debug cache network

Arborescence du projet PWA

 

En partant d’une application web, vous devez avoir a minima deux nouveaux fichiers :

  • Un fichier JavaScript (sw.js) ;
  • Un fichier web manifest (manifest.webmanifest).

Ci-dessous, un exemple de projet sans Framework/librairie JavaScript :

exemple de projet sans Framework/librairie JavaScript :

Documentation utile pour aller plus loin

 

Nous espérons que ces deux articles vous ont donné envie de vous lancer dans le développement de votre première application PWA, pour tester les concepts que nous avons vus et pourquoi pas créer une application qui va se retrouver sur les stores !

Pour finir, voici quelques liens utiles pour continuer :

Le code source du projet illustrant cet article est disponible sur Github.