Service Workers mais novos, por padrão

Texto longo, leia o resumo

A partir do Chrome 68, as solicitações HTTP que verificam se há atualizações para o script do service worker não mais preenchidos pelo cache HTTP por padrão. Isso resolve um ponto problemático comum de desenvolvimento, em que a configuração de um cabeçalho Cache-Control inadvertida no script do service worker pode levar devido a atualizações atrasadas.

Se você já tiver desativado o armazenamento em cache HTTP para seu script /service-worker.js veiculando-o com Cache-Control: max-age=0, não haverá alterações devido ao novo padrão do seu modelo.

Além disso, a partir do Chrome 78, a comparação byte por byte será aplicados a scripts carregados em um service worker por meio de importScripts() Qualquer alteração feita em um script importado acionará a fluxo de atualização de service workers, assim como faria uma alteração no service worker de nível superior.

Contexto

Sempre que você navegar para uma nova página que está no escopo de um service worker, chame registration.update() explicitamente. de JavaScript ou quando um service worker é "acordado" por um evento push ou sync, o navegador solicita, em paralelo, o recurso JavaScript que foi originalmente transmitido à navigator.serviceWorker.register() para procurar atualizações no script do service worker.

Para os fins deste artigo, vamos supor que o URL seja /service-worker.js e que ele contém uma única chamada para importScripts(), que carrega o código adicional que é executado dentro do service worker:

// Inside our /service-worker.js file:
importScripts('path/to/import.js');

// Other top-level code goes here.

O que muda?

Antes do Chrome 68, a solicitação de atualização do /service-worker.js seria feita pelo cache HTTP. (como a maioria das buscas é). Isso significava que, se o script foi originalmente enviado com Cache-Control: max-age=600, as atualizações nos próximos 600 segundos (10 minutos) não iriam para a rede, então o usuário pode não receber a versão mais atualizada do service worker. No entanto, se max-age fosse mais de 86.400 (24 horas), isso seria tratado como se fosse 86.400, para evitar que os usuários fiquem presos com determinada versão para sempre.

A partir da versão 68, o cache HTTP será ignorado ao solicitar atualizações para o service worker. script, de modo que os aplicativos da web existentes podem ver um aumento na frequência de solicitações para seus script do service worker. As solicitações de importScripts ainda serão feitas pelo cache HTTP. Mas isso é apenas o padrão: uma nova opção de registro, updateViaCache está disponível, que oferece controle sobre esse comportamento.

updateViaCache

Agora, os desenvolvedores podem transmitir uma nova opção ao chamar navigator.serviceWorker.register(): o parâmetro updateViaCache. Ele usa um destes três valores: 'imports', 'all' ou 'none'.

Os valores determinam se e como o cache HTTP padrão do navegador entra em jogo ao fazer a solicitação HTTP para verificar se há recursos atualizados do service worker.

  • Quando definido como 'imports', o cache HTTP nunca será consultado durante a verificação de atualizações para o /service-worker.js, mas será consultado ao buscar qualquer script importado (path/to/import.js, em nosso exemplo). Esse é o padrão e corresponde ao comportamento inicial no Chrome 68.

  • Quando definido como 'all', o cache HTTP será consultado ao fazer solicitações para os script /service-worker.js de nível superior, bem como todos os scripts importados dentro do serviço worker, como path/to/import.js. Essa opção corresponde ao comportamento anterior no Chrome, anteriores ao Chrome 68.

  • Quando definido como 'none', o cache HTTP não será consultado ao fazer solicitações para os /service-worker.js de nível superior ou para qualquer script importado, como os path/to/import.js

Por exemplo, o código a seguir registrará um service worker e garantirá que o cache HTTP seja nunca consultada ao verificar se há atualizações para o script /service-worker.js, ou para qualquer scripts referenciados por importScripts() dentro de /service-worker.js:

if ('serviceWorker' in navigator) {
  navigator.serviceWorker.register('/service-worker.js', {
    updateViaCache: 'none',
    // Optionally, set 'scope' here, if needed.
  });
}

Verifica se há atualizações para scripts importados

Antes do Chrome 78, qualquer script de service worker carregado por importScripts() seriam recuperados somente uma vez (verificando primeiro no cache HTTP ou por meio do rede, dependendo da configuração de updateViaCache). Depois dessa data , ela seria armazenada internamente pelo navegador e jamais voltaria a ser buscada.

A única maneira de forçar um service worker já instalado a captar alterações em um script importado era alterar o URL do script, geralmente adicionando um valor semver (por exemplo, importScripts('https://example.com/v1.1.0/index.js')) ou pela inclusão de um hash de o conteúdo (por exemplo, importScripts('https://example.com/index.abcd1234.js')). Um efeito colateral de alterar o URL importado é que o service worker de nível superior o conteúdo do script mudar, o que, por sua vez, aciona o Fluxo de atualização do service worker.

A partir do Chrome 78, sempre que uma verificação de atualização for realizada em um service worker, serão feitas verificações ao mesmo tempo para determinar se o conteúdo dos scripts importados foi alterado. Dependendo Cache-Control cabeçalhos usados, essas verificações de script importado podem ser atendidas pelo o cache HTTP se updateViaCache for definido como 'all' ou 'imports' (que é o valor padrão), ou as verificações podem ir diretamente para a rede se updateViaCache está definido como 'none'.

Se uma verificação de atualização para um script importado resultar em uma diferença byte por byte comparado ao que estava armazenado anteriormente pelo service worker, que por sua vez, acionarão o fluxo completo de atualização do service worker, mesmo que o arquivo de worker permanece o mesmo.

O comportamento do Chrome 78 corresponde ao que o Firefox implemented há vários anos, no Firefox 56. O Safari já implementa esse comportamento, pois muito bem.

O que os desenvolvedores precisam fazer?

Se você tiver desativado o armazenamento em cache HTTP para seu script /service-worker.js veiculando-o com Cache-Control: max-age=0 (ou um valor semelhante), você não verá nenhuma alteração devido a o novo comportamento padrão.

Se você disponibilizar seu script /service-worker.js com o armazenamento em cache HTTP ativado, seja intencionalmente ou porque ele é apenas o padrão para seu ambiente de hospedagem, talvez você comece a ver um aumento de solicitações HTTP adicionais para /service-worker.js feitas em seu servidor, ou seja, solicitações que costumavam ser atendidas pelo cache HTTP. Se você quiser continue permitindo que o valor do cabeçalho Cache-Control influencie a atualização das suas /service-worker.js, você vai precisar começar a definir explicitamente updateViaCache: 'all' quando registrar o service worker.

Dado que pode haver uma cauda longa de usuários em versões de navegadores mais antigas, ainda é uma boa ideia continue definindo o cabeçalho HTTP Cache-Control: max-age=0 nos scripts do service worker, mesmo que navegadores mais recentes podem ignorá-los.

Os desenvolvedores podem usar essa oportunidade para decidir se querem ativar explicitamente as scripts do armazenamento em cache HTTP agora e adicionar updateViaCache: 'none' ao service worker registro, se for o caso.

Exibição de scripts importados

A partir do Chrome 78, os desenvolvedores poderão ver mais solicitações HTTP recebidas para recursos carregados via importScripts(), já que agora eles serão verificados atualizações.

Para evitar esse tráfego HTTP adicional, configure um cabeçalhos Cache-Control ao disponibilizar scripts que incluem semver ou hashes em os URLs delas e dependem do comportamento updateViaCache padrão de 'imports'.

Como alternativa, se você quiser que os scripts importados sejam verificados quanto à presença atualizações, veicule-as com Cache-Control: max-age=0 ou que você use updateViaCache: 'none'.

Leitura adicional

"O ciclo de vida do Service Worker" e "Práticas recomendadas de armazenamento em cache pegadinhas de max-age", de Jake Archibald, são leituras recomendadas para todos os desenvolvedores que implantam algo na Web.