Medir o desempenho em um service worker

Além de Jake Archibald se preocupar com a decadência e a falta de habilidades de desenvolvedor, ele argumentou que, usando o service worker de maneira inteligente, é possível melhorar muito o desempenho do seu site ou app. Assista ao vídeo para ter uma visão geral.

Se você for sobrecarregar seu tempo de carregamento da página, como sugere Jake, você precisará entender como os service workers afetam as solicitações de sua página.

A Resource Timing e a API User Timing são componentes essenciais na infraestrutura de monitoramento real de usuários (RUM, na sigla em inglês) de sites porque permitem entender de forma abrangente como todos os usuários veem o desempenho do site (outro caso de uso é detectar a injeção de conteúdo). Em resumo, você pode entender praticamente todos os aspectos de todas as solicitações da Web feitas no seu site, a menos que haja um service worker ou um Web worker.

Veja um exemplo rápido de como ele pode ser usado para receber uma lista de todas as solicitações feitas a um domínio que não é o atual.

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

As APIs Resource Timing e User Timing foram criadas e implementadas antes que o service worker fosse um brilho para os engenheiros, e o código acima não conseguia entender como isso foi afetado pelo service worker.

Um conjunto recente de mudanças no Chrome 45 (Beta em julho de 2015) ajudará você ao introduzir a possibilidade de todas as formas de workers (Web e service worker) acessarem as APIs Resource Timing e User Timing e a atualizar o desempenho da rede para todos os usuários.

Como acessar métricas de desempenho de um service worker

A maior mudança é a adição do objeto performance a um contexto de Workers (Web e ServiceWorkers). Isso vai permitir que você entenda os tempos de desempenho de todas as solicitações feitas no contexto do worker, além de definir suas próprias marcas para medir a execução do JS. Se você só conseguisse ver o que acontece no contexto da janela atual, perderia informações de tempo importantes de:

  • Solicitações fetch() feitas dentro do evento oninstall do service worker
  • As solicitações fetch() feitas ao armazenar dados em cache em um evento onpush agora podem ser rastreadas para entender o desempenho mostrado aos usuários.
  • Por fim, a solicitação fetch() que é feita e interceptada pelo gerenciador onfetch.

O último ponto é importante. Um service worker é como um proxy que fica entre a IU da Web e a rede. O objeto performance na window só vê os tempos e as informações da parte da solicitação que ele invoca. Ele não tem conhecimento do service worker entre o cliente e a rede, de modo que não consegue entender o impacto do service worker.

Como posso usar isso?

Um service worker típico que oferece suporte off-line primeiro teria uma etapa de instalação em que fará o download e salvará todos os recursos para uso posterior

Um exemplo de onde isso pode ser usado é para gravar e registrar os dados de tempo da etapa de instalação. Assim, é possível tomar algumas decisões medidas sobre como melhorar o desempenho da instalação com base no uso real do usuário.

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

Atualmente, muitos sites usam o RUM para entender a experiência da maioria dos usuários. Ferramentas como o Google Analytics já informam dados de velocidade do site usando a API Navigation Timing, mas precisam ser atualizadas para incluir a análise de desempenho de um contexto de worker.

A API Navigation Timing chegará aos service workers?

No momento, não há planos para adicionar a API Navigation Timing ao contexto do service worker, porque não há navegações tradicionais em um service worker. O interessante é que, para o service worker, cada navegação no conjunto de páginas controlado dele parece uma busca de recursos. Por si só, isso torna os service workers uma maneira incrivelmente convincente de centralizar a maior parte da lógica de desempenho no seu app da Web.

Posso ver o que mudou?

Tenho interesse na discussão e especificações