Leistung in einem Service Worker messen

Jake Archibald machte sich nicht nur Sorgen, dass seine Entwicklerfähigkeiten verkümmern, sondern er machte auch deutlich, dass Sie mithilfe von Service Workern die Leistung Ihrer Website oder App drastisch verbessern können. Sehen Sie sich das Video an, um einen Überblick zu erhalten.

Wenn Sie die Ladezeit Ihrer Seite wie Jake vorschlägt optimieren möchten, müssen Sie wirklich verstehen, wie sich Dienstprogramme auf die Anfragen Ihrer Seite auswirken.

Die Resource Timing API und die User Timing API sind wichtige Komponenten in der RUM-Infrastruktur (Real User Monitoring) vieler Websites, da sie Ihnen einen ganzheitlichen Überblick darüber geben, wie alle Ihre Nutzer die Leistung Ihrer Website wahrnehmen. Ein weiterer Anwendungsfall ist die Erkennung von Content-Injection. Kurz gesagt: Sie können damit fast jeden Aspekt jeder Webanfrage nachvollziehen, die von Ihrer Website gesendet wird, es sei denn, Sie haben einen Service- oder Webworker.

Hier ein kurzes Beispiel, wie Sie damit eine Liste aller Anfragen abrufen können, die an eine Domain gesendet wurden, die nicht die aktuelle Domain ist.

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;
};

Die Resource Timing API und die User Timing API wurden erstellt und implementiert, bevor Service Worker in den Blick der Entwickler gerieten. Mit dem Code oben lässt sich nicht nachvollziehen, wie sich der Service Worker auf die Leistung ausgewirkt hat.

Durch die jüngsten Änderungen in Chrome 45 (Betaversion im Juli 2015) können Sie die Netzwerkleistung für alle Ihre Nutzer im Blick behalten. Alle Arten von Workern (Web- und Dienst-Worker) haben jetzt Zugriff auf die Resource Timing API und die User Timing API.

Über einen Service Worker auf Leistungsmesswerte zugreifen

Die größte Änderung ist das Hinzufügen des performance-Objekts in einen Worker-Kontext (Web- und ServiceWorkers). So können Sie jetzt die Leistungszeitpunkte aller Anfragen nachvollziehen, die im Kontext des Workers gesendet werden. Außerdem können Sie eigene Markierungen für die Messung der JS-Ausführung festlegen. Wenn Sie nur sehen können, was im Kontext des aktuellen Fensters passiert, gehen Ihnen wichtige Informationen zum Timing verloren:

  • fetch() Anfragen, die im oninstall-Ereignis des Service Workers gesendet wurden
  • fetch()-Anfragen, die beim Caching von Daten in einem onpush-Ereignis gesendet werden, können jetzt nachverfolgt werden, um die Leistung zu ermitteln, die Nutzer sehen.
  • Schließlich werden fetch()-Anfragen vom onfetch-Handler gesendet und abgefangen.

Der letzte Punkt ist wichtig. Sie können sich einen Service Worker als Proxy vorstellen, der zwischen der Web-UI und dem Netzwerk liegt. Das performance-Objekt auf dem window sieht nur die Zeitangaben und Informationen für den Teil der Anfrage, den es aufruft. Es hat keine Kenntnis vom Dienst-Worker, der sich zwischen dem Client und dem Netzwerk befindet, und kann daher die Auswirkungen des Dienst-Workers nicht nachvollziehen.

Wie kann ich das verwenden?

Ein typischer Service Worker, der zuerst offline unterstützt wird, hat einen Installationsschritt, bei dem alle Assets heruntergeladen und zur späteren Verwendung gespeichert werden.

Ein Beispiel für eine solche Verwendung wäre die Aufzeichnung und Protokollierung der Zeitdaten des Installationsschritts, damit Sie fundierte Entscheidungen darüber treffen können, wie Sie die Leistung Ihrer Installation auf der Grundlage der tatsächlichen Nutzung durch Nutzer verbessern können.

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;
        })
    );
});

Viele Websites nutzen heute RUM, um zu verstehen, wie die Mehrheit ihrer Nutzer ihre Website erlebt. Mit Tools wie Google Analytics werden bereits Daten zur Websitegeschwindigkeit mithilfe der Navigation Timing API erfasst. Sie müssen jedoch aktualisiert werden, um eine Leistungsanalyse aus einem Worker-Kontext zu ermöglichen.

Wird die Navigation Timing API für Service Worker eingeführt?

Derzeit ist nicht geplant, die Navigation Timing API dem Service Worker-Kontext hinzuzufügen, da es in einem Service Worker keine herkömmlichen Navigationen gibt. Interessant ist, dass für den Service Worker jede Navigation auf den vom Service Worker verwalteten Seiten wie ein Ressourcenabruf aussieht. Allein dadurch sind Service Worker eine unglaublich überzeugende Möglichkeit, den Großteil Ihrer Leistungslogik in Ihrer Webanwendung zu zentralisieren.

Kann ich sehen, was sich geändert hat?

Ich interessiere mich für die Diskussion und die technischen Daten.