在 Service Worker 中衡量性能

除了 Jake Archibald 担心自己的开发者技能腐败和掉落之外,他还坚信,通过智能地使用 Service Worker,您可以显著提高网站或应用的性能。请观看相关视频,简要了解。

如果您打算按照 Jake 的建议提高网页加载时间,那么您确实需要了解 Service Worker 如何影响您页面的请求。

Resource TimingUser Timing API 是许多网站 RUM(真实用户监控)基础架构的关键组成部分,因为它可以让您全面了解所有用户对您网站性能的看法(另一个用例是检测内容注入)。简而言之,除非您有 Service Worker 或 Web Worker,否则它可以让您了解网站发出的每个 Web 请求的几乎所有方面。

下面这个简短的示例演示了如何使用它来获取对当前网域以外的网域发出的所有请求的列表。

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

Resource Timing API 和 User Timing API 是在 Service Worker 逐渐亮起之前创建并实现的,以上代码无法理解 Service Worker 对其的影响。

Chrome 45(2015 年 7 月 Beta 版)中最近进行了一系列更改,这些更改将帮助您:让所有形式的工作器(Web 和 Service Worker)能够访问 Resource Timing API 和 User Timing API,从而让您能够随时掌握所有用户的网络性能。

从 Service Worker 访问性能指标

最大的变化是将 performance 对象添加到了 worker 上下文(Web 和 ServiceWorker),它现在可让您了解在 worker 环境中发出的所有请求的性能时间,并且您还可以设置自己的标记来衡量 JS 的执行情况。如果您只能看到在当前窗口的上下文中发生的情况,则会错过以下重要时间信息:

  • 在 Service Worker 的 oninstall 事件内发出的 fetch() 请求
  • 您现在可以跟踪在 onpush 事件中缓存数据时发出的 fetch() 请求,以了解用户看到的性能。
  • 最后是 onfetch 处理程序发出并拦截的 fetch() 请求。

最后一点很重要。可以将 Service Worker 视为位于网页界面和网络之间的代理。window 上的 performance 对象只能看到其调用的请求部分的时间和信息,它不知道位于客户端和网络之间的 Service Worker,因此无法了解 Service Worker 的影响。

如何使用?

最先支持离线操作的典型 Service Worker 会经历一个安装步骤,在该步骤中,它会下载并保存所有资源以供日后使用

举例来说,您可以记录并记录安装步骤的时间数据,以便根据实际用户使用情况做出一些衡量决策,从而衡量如何提升安装效果。

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

如今,许多网站都使用 RUM 来了解其大多数用户的使用体验。Google Analytics(分析)等工具已使用 Navigation Timing API 报告网站速度数据,但需要更新才能包含来自工作器上下文的性能分析。

Navigation Timing API 是否会到达 Service Worker

目前还没有关于将 Navigation Timing API 添加到 Service Worker 上下文的计划,因为 Service Worker 中没有传统的导航方式。有趣的是,对 Service Worker 而言,其受控页面集中的每次导航都看起来像一次获取资源。仅凭这一点就使得 Service Worker 就成了一种极具吸引力的方式,能够将大部分性能逻辑集中到 Web 应用中。

我能看到具体变化吗?

我对相关讨论和规范感兴趣