Les Progressive Web Apps combinent le meilleur des sites web et des applications natives. Elles se chargent comme des pages web, mais offrent des fonctionnalités dignes d'une application : elles fonctionnent hors ligne, peuvent être installées sur l'écran d'accueil, envoient des notifications push et se lancent dans leur propre fenêtre. Des entreprises comme Twitter, Pinterest ou Starbucks ont constaté des améliorations spectaculaires de l'engagement et des conversions après être passées aux PWA.

Qu'est-ce qui fait une PWA ?

Une PWA est un site web qui remplit trois critères :

  • HTTPS : Servi via une connexion sécurisée (indispensable pour les service workers)
  • Service Worker : Un fichier JavaScript qui s'exécute en arrière-plan et gère la mise en cache ainsi que le mode hors ligne
  • Manifeste d'application web : Un fichier JSON qui indique au navigateur comment afficher l'application une fois installée

Le manifeste d'application web

manifest.json
{
  "name": "Mon Application Géniale",
  "short_name": "MonApp",
  "description": "Une application web progressive",
  "start_url": "/",
  "display": "standalone",
  "background_color": "#0f172a",
  "theme_color": "#6366f1",
  "icons": [
    { "src": "/icons/icon-192.png", "sizes": "192x192", "type": "image/png" },
    { "src": "/icons/icon-512.png", "sizes": "512x512", "type": "image/png" },
    { "src": "/icons/icon-512-maskable.png", "sizes": "512x512", "type": "image/png", "purpose": "maskable" }
  ]
}
Lien dans le HTML
<link rel="manifest" href="/manifest.json">
<meta name="theme-color" content="#6366f1">

Les service workers

Un service worker est un fichier JavaScript qui s'exécute dans un fil d'exécution distinct de votre page principale. Il intercepte les requêtes réseau, gère un cache et peut servir du contenu lorsque l'utilisateur est hors ligne.

Enregistrer un service worker
// Dans votre app.js principal
if ('serviceWorker' in navigator) {
  window.addEventListener('load', async () => {
    try {
      const reg = await navigator.serviceWorker.register('/sw.js');
      console.log('SW enregistré :', reg.scope);
    } catch (err) {
      console.error('Échec de l\'enregistrement du SW :', err);
    }
  });
}
sw.js — Stratégie Cache First
const CACHE_NAME = 'v1';
const ASSETS = [
  '/',
  '/css/style.css',
  '/js/app.js',
  '/offline.html',
];

// Install — mettre en cache les ressources essentielles
self.addEventListener('install', (event) => {
  event.waitUntil(
    caches.open(CACHE_NAME)
      .then(cache => cache.addAll(ASSETS))
      .then(() => self.skipWaiting())
  );
});

// Activate — nettoyer les anciens caches
self.addEventListener('activate', (event) => {
  event.waitUntil(
    caches.keys().then(keys =>
      Promise.all(keys
        .filter(key => key !== CACHE_NAME)
        .map(key => caches.delete(key))
      )
    )
  );
});

// Fetch — servir depuis le cache, sinon passer par le réseau
self.addEventListener('fetch', (event) => {
  event.respondWith(
    caches.match(event.request)
      .then(cached => cached || fetch(event.request))
      .catch(() => caches.match('/offline.html'))
  );
});

Les stratégies de mise en cache

  • Cache First : Consulter d'abord le cache, puis se rabattre sur le réseau. Idéal pour les ressources statiques (CSS, JS, images).
  • Network First : Essayer d'abord le réseau, puis se rabattre sur le cache. Idéal pour les données d'API et les pages HTML.
  • Stale While Revalidate : Servir immédiatement depuis le cache, puis le mettre à jour depuis le réseau en arrière-plan. Idéal pour les contenus fréquemment actualisés.
  • Network Only : Toujours passer par le réseau. Pour les requêtes non mises en cache (POST, API authentifiées).

Rendre l'application installable

Lorsque votre PWA remplit les critères d'installation (HTTPS, manifeste, service worker), les navigateurs affichent une invite d'installation. Vous pouvez aussi la déclencher par programmation :

Bouton d'installation personnalisé
let deferredPrompt;

window.addEventListener('beforeinstallprompt', (e) => {
  e.preventDefault();
  deferredPrompt = e;
  document.getElementById('install-btn').style.display = 'block';
});

document.getElementById('install-btn').addEventListener('click', async () => {
  if (!deferredPrompt) return;
  deferredPrompt.prompt();
  const { outcome } = await deferredPrompt.userChoice;
  console.log(`L'utilisateur a ${outcome === 'accepted' ? 'installé' : 'refusé'} la PWA`);
  deferredPrompt = null;
});

Tester votre PWA

  • Chrome DevTools → onglet Application — inspectez le manifeste, le service worker et le stockage du cache
  • Audit Lighthouse — lancez un audit PWA pour vérifier tous les critères
  • Test hors ligne — activez « Offline » dans l'onglet Network des DevTools

Essayez nos outils de performance gratuits

Minifiez votre JavaScript et votre CSS pour un chargement plus rapide de votre PWA.