Mesurer les performances dans un service worker

Jake Archibald s'inquiète de la détérioration de ses compétences de développeur, mais il a démontré de manière convaincante qu'en utilisant intelligemment un service worker, vous pouvez considérablement améliorer les performances de votre site ou de votre application. Regardez la vidéo pour en savoir plus.

Si vous souhaitez accélérer le temps de chargement de votre page comme Jake le suggère, vous devez vraiment comprendre comment les services workers affectent les requêtes de votre page.

Les API Resource Timing et User Timing sont des composants essentiels dans l'infrastructure RUM (Real User Monitoring) de nombreux sites, car elles vous permettent de comprendre de manière globale comment tous vos utilisateurs perçoivent les performances de votre site (un autre cas d'utilisation est la détection de l'injection de contenu). En bref, il vous permet de comprendre presque tous les aspects de chaque requête Web effectuée à partir de votre site, sauf si vous disposez d'un service worker ou d'un worker Web.

Voici un exemple rapide de la façon dont vous pouvez l'utiliser pour obtenir la liste de toutes les requêtes envoyées à un domaine qui n'est pas le domaine actuel.

var getThirdPartyRequests = function() {
    var thirdPartyRequests = [];
    var requests = window.performance.getEntriesByType("resource");
    
    var currentHost = window.location.host

    for(var requestIdx = 0; requestIdx < requests.length; requestIdx++) {
    var request = requests[requestIdx];
    var url = new URL(request.name);
    var host = url.host;

    if(host != currentHost) {
        thirdPartyRequests.push(request);
    }
    }
    
    return thirdPartyRequests;
};

Les API Resource Timing et User Timing ont été créées et implémentées avant que le service worker ne soit même envisagé par les ingénieurs. Le code ci-dessus ne pourrait pas comprendre l'impact du service worker.

Un ensemble récent de modifications apportées à Chrome 45 (bêta en juillet 2015) vous aidera en permettant à toutes les formes de workers (Web et service worker) d'accéder aux API Resource Timing et User Timing. Vous pourrez ainsi garder un œil sur les performances réseau de tous vos utilisateurs.

Accéder aux métriques de performances à partir d'un service worker

Le plus grand changement est l'ajout de l'objet performance dans un contexte de workers (Web et ServiceWorkers) qui vous permettra désormais de comprendre les délais de performances de toutes les requêtes effectuées dans le contexte du worker, et de définir vos propres repères pour mesurer l'exécution du code JavaScript. Si vous ne pouvez voir que ce qui se passe dans le contexte de la fenêtre actuelle, vous manquerez des informations temporelles critiques provenant des éléments suivants:

  • Requêtes fetch() effectuées dans l'événement oninstall du service worker
  • Les requêtes fetch() effectuées lors du mise en cache de données dans un événement onpush peuvent désormais être suivies pour comprendre les performances que vos utilisateurs voient.
  • Enfin, les requêtes fetch() effectuées et interceptées par le gestionnaire onfetch.

Le dernier point est important. Vous pouvez considérer un service worker comme un proxy situé entre l'UI Web et le réseau. L'objet performance sur le window ne voit que les délais et les informations de la partie de la requête qu'il appelle. Il n'a aucune connaissance du service worker situé entre le client et le réseau, et ne peut donc pas comprendre l'impact du service worker.

Comment puis-je l'utiliser ?

Un service worker typique qui prend en charge le mode hors connexion en priorité comporte une étape d'installation au cours de laquelle il télécharge et enregistre tous les éléments à utiliser ultérieurement.

Par exemple, vous pouvez enregistrer et consigner les données temporelles de l'étape d'installation afin de prendre des décisions mesurées sur la façon d'améliorer les performances de votre installation en fonction de l'utilisation réelle des utilisateurs.

self.addEventListener("install", function() {
    var urls = [
    '/',
    '/images/chrome-touch-icon-192x192.png',
    '/images/ic_add_24px.svg',
    '/images/side-nav-bg@2x.jpg',
    '/images/superfail.svg',
    '/scripts/voicememo-core.js',
    '/styles/voicememo-core.css',
    '/third_party/Recorderjs/recorder.js',
    '/third_party/Recorderjs/recorderWorker.js',
    '/third_party/Recorderjs/wavepcm.js',
    '/third_party/moment.min.js',
    '/favicon.ico',
    '/manifest.json'
    ];

    urls = urls.map(function(url) {
    return new Request(url, {credentials: 'include'});
    });

    event.waitUntil(
    caches
        .open(CACHE_NAME + '-v' + CACHE_VERSION)
        .then(function(cache) {
        // Fetch all the URL's and store in the cache
        return cache.addAll(urls);
        })
        .then(function () {
        // Analyze all the requests
        var requests = self.performance.getEntriesByType("resource");
        
        // Loop across all the requests and save the timing data.
        return;
        })
    );
});

De nos jours, de nombreux sites utilisent la RUM pour comprendre comment la majorité de leurs utilisateurs interagissent avec leur site. Des outils tels que Google Analytics génèrent déjà des rapports sur les données de vitesse du site à l'aide de l'API Navigation Timing, mais ils devront être mis à jour pour inclure l'analyse des performances à partir d'un contexte de worker.

L'API Navigation Timing arrivera-t-elle dans les service workers ?

Pour le moment, nous ne prévoyons pas d'ajouter l'API Navigation Timing au contexte du service worker, car il n'y a pas de navigations traditionnelles dans un service worker. L'élément intéressant est que, pour le service worker, chaque navigation dans l'ensemble de pages contrôlé par le service worker ressemble à une récupération de ressources. Cela seul fait des service workers un moyen incroyablement intéressant de centraliser la majorité de votre logique de performances dans votre application Web.

Puis-je voir ce qui a changé ?

Je suis intéressé par la discussion et les spécifications