Atualizar

Você publicou seu PWA. Alguns usuários o usam pelo navegador, outros o instalam nos dispositivos. Ao atualizar o app, é importante aplicar as práticas recomendadas para evitar armadilhas.

Você pode atualizar:

  • Dados de apps.
  • Recursos já armazenados em cache nos dispositivos.
  • O arquivo do service worker ou as dependências dele.
  • Metadados do manifesto.

Vamos conferir as práticas recomendadas para cada um desses elementos.

Atualização de dados

Para atualizar dados, como os armazenados no IndexedDB, use ferramentas como Fetch, WebRTC ou a API WebSockets. Se o aplicativo for compatível com recursos off-line, lembre-se de manter atualizados os dados de suporte aos recursos.

Em navegadores compatíveis, há opções para sincronizar dados, não apenas quando o usuário abre o PWA, mas também em segundo plano. Essas opções são:

  • Sincronização em segundo plano: salva solicitações que falharam e tenta fazê-las novamente usando a sincronização do service worker.
  • Sincronização periódica na Web em segundo plano: sincroniza dados periodicamente em segundo plano, em momentos específicos, permitindo que o app forneça dados atualizados, mesmo que o usuário ainda não tenha aberto o app.
  • Busca em segundo plano: faz o download de arquivos grandes mesmo quando o PWA está fechado.
  • Push na Web: envia uma mensagem do servidor que ativa o service worker e notifica o usuário. Isso é comumente chamado de "notificação push". Essa API requer a permissão do usuário.

Todas essas APIs são executadas a partir do contexto do service worker. No momento, elas estão disponíveis apenas em navegadores baseados no Chromium, em sistemas operacionais Android e em computadores. Ao usar uma dessas APIs, é possível executar o código na linha de execução do service worker. por exemplo, para fazer o download de dados do seu servidor e atualizar os dados do IndexedDB.

Atualizando recursos

A atualização de recursos inclui todas as alterações feitas nos arquivos usados para renderizar a interface do app, como HTML, CSS, JavaScript e imagens. Por exemplo, uma mudança na lógica do aplicativo, uma imagem que faz parte da interface ou uma folha de estilo CSS.

Atualizar padrões

Aqui estão alguns padrões comuns para lidar com atualizações de apps, mas você sempre pode personalizar o processo de acordo com suas necessidades:

  • Atualização completa: qualquer alteração, mesmo que seja pequena, aciona a substituição de todo o conteúdo do cache. Esse padrão imita como apps específicos do dispositivo lidam com as atualizações, além de consumir mais largura de banda e levar mais tempo.
  • Atualização de recursos alterados: somente os recursos que foram alterados desde a última atualização são substituídos em cache. Ela geralmente é implementada usando uma biblioteca como a Workbox. Isso envolve a criação de uma lista de arquivos armazenados em cache, uma representação em hash do arquivo e carimbos de data/hora. Com essas informações, o service worker compara essa lista com os recursos armazenados em cache e decide quais recursos atualizar.
  • Atualização de recursos individuais: os recursos são atualizados individualmente quando são alterados. A estratégia desatualizada ao revalidar descrita no capítulo "Exibição" é um exemplo de atualização individual de recursos.

Quando atualizar

Outra boa prática é encontrar um bom momento para verificar as atualizações e aplicá-las. Veja algumas opções:

  • Quando o service worker é ativado. Não há evento para detectar neste momento, mas o navegador executará qualquer código no escopo global do service worker quando for ativado.
  • No contexto da janela principal do PWA, após o navegador carregar a página, para evitar que o app carregue mais lentamente.
  • Quando eventos em segundo plano são acionados, como quando seu PWA recebe uma notificação push ou uma sincronização em segundo plano é acionada. Então, você poderá atualizar seu cache, e seus usuários terão a nova versão do recurso na próxima vez que abrirem o aplicativo.
.

Atualizações ao vivo

Também é possível escolher se você quer aplicar uma atualização quando o app estiver aberto (ao vivo) ou fechado. Com a abordagem fechada, mesmo que o app tenha feito o download de novos recursos, ele não fará mudanças e usará as novas versões no próximo carregamento.

Uma atualização em tempo real significa que, assim que o recurso é atualizado no cache, seu PWA substitui o recurso no carregamento atual. Essa é uma tarefa complexa que não será abordada neste curso. Algumas ferramentas que ajudam a implementar essa atualização são livereload-js e atualização dos recursos CSS API CSSStyleSheet.replace().

Como atualizar o service worker

O navegador aciona um algoritmo de atualização quando o service worker ou as dependências dele mudam. O navegador detecta atualizações usando uma comparação byte a byte entre os arquivos armazenados em cache e os recursos provenientes da rede.

Em seguida, o navegador tenta instalar a nova versão do service worker, e o novo service worker fica no estado waiting, conforme descrito no capítulo Service workers. A nova instalação executará o evento install para o novo service worker. Se você estiver armazenando recursos em cache nesse manipulador de eventos, os recursos também serão armazenados em cache novamente.

.

Como detectar alterações no service worker

Para detectar se um novo service worker está pronto e instalado, usamos o evento updatefound do registro do service worker. Este evento é disparado quando o novo service worker começa a ser instalado. É preciso esperar que o estado mude para installed com o evento statechange. consulte o seguinte:

async function detectSWUpdate() {
  const registration = await navigator.serviceWorker.ready;

  registration.addEventListener("updatefound", event => {
    const newSW = registration.installing;
    newSW.addEventListener("statechange", event => {
      if (newSW.state == "installed") {
         // New service worker is installed, but waiting activation
      }
    });
  })
}

Forçar substituição

O novo service worker será instalado, mas aguardando a ativação por padrão. A espera impede que o novo service worker assuma clientes antigos que podem não ser compatíveis com a nova versão.

Mesmo que não seja recomendado, o novo service worker pode pular esse período de espera e iniciar a ativação imediatamente.

self.addEventListener("install", event => {
   // forces a service worker to activate immediately
   self.skipWaiting();
  });

self.addEventListener("activate", event => {
  // when this SW becomes activated, we claim all the opened clients
  // they can be standalone PWA windows or browser tabs
  event.waitUntil(clients.claim());
});

O evento controllerchange é disparado quando o service worker que controla a página atual muda. Por exemplo, um novo worker ignorou a espera e se tornou o novo worker ativo.

navigator.serviceWorker.addEventListener("controllerchange", event => {
   // The service worker controller has changed
 });

Atualizar metadados

Você também pode atualizar os metadados do app, que são definidos principalmente no manifesto do app da Web. Por exemplo, atualize o ícone, o nome ou o URL de início do app ou adicione um novo recurso, como os atalhos de apps. Mas o que acontece com todos os usuários que já instalaram o aplicativo com o ícone antigo em seus dispositivos? Como e quando eles recebem a versão atualizada?

A resposta depende da plataforma. Vamos conferir as opções disponíveis.

Safari nos navegadores iOS, iPadOS e Android

Nessas plataformas, a única maneira de receber os novos metadados do manifesto é reinstalar o app pelo navegador.

Google Chrome no Android com WebAPK

Quando o usuário instalar o PWA no Android usando o Google Chrome com o WebAPK ativado (a maioria das instalações do PWA do Chrome), a atualização será detectada e aplicada com base em um algoritmo. Confira os detalhes neste artigo sobre as atualizações do manifesto.

Algumas observações adicionais sobre o processo:

Se o usuário não abrir o PWA, o WebAPK não será atualizado. Se o servidor não responder com o arquivo de manifesto (o erro 404 ocorrer), o Chrome não vai verificar se há atualizações por no mínimo 30 dias, mesmo que o usuário abra o PWA.

Acesse about:webapks no Chrome para Android para conferir o status de "atualização necessária" e solicita uma atualização. Leia mais sobre essa ferramenta de depuração no capítulo Ferramentas e depuração.

Samsung Internet no Android com WebAPK

O processo é parecido com o da versão do Chrome. Nesse caso, se o manifesto do PWA exigir uma atualização, o WebAPK será atualizado na rede Wi-Fi nas 24 horas seguintes após criar o WebAPK atualizado.

Google Chrome e Microsoft Edge no computador

Em dispositivos desktop, quando o PWA é iniciado, o navegador determina a última vez que verificou se há mudanças no manifesto local. Se o manifesto não tiver sido analisado desde que o navegador foi iniciado pela última vez ou não tiver sido verificado nas últimas 24 horas, o navegador fará uma solicitação de rede para o manifesto e o comparará com a cópia local.

Quando as propriedades selecionadas forem atualizadas, isso vai acionar uma atualização depois que todas as janelas forem fechadas.

Alertar o usuário

Algumas estratégias de atualização precisam de uma atualização ou de uma nova navegação dos clientes. Informe ao usuário que há uma atualização em espera, mas dê a ele a chance de atualizar a página quando for melhor para ele.

Para informar o usuário, existem estas opções:

  • Use o DOM ou a API canvas para renderizar um aviso na tela.
  • Use a API Web Notifications. Essa API faz parte da permissão push para gerar uma notificação no sistema operacional. Você precisará solicitar a permissão de push na Web para usá-lo, mesmo que não use o protocolo de mensagens push do seu servidor. Essa é a única opção que temos se o PWA não estiver aberto.
  • Use a API de selos para mostrar que as atualizações estão disponíveis no ícone de instalação do PWA

Uma notificação de atualização mostrada no DOM..

Mais sobre a API Badging

Com a API de selos, você pode marcar o ícone do PWA com um número ou um ponto de selo em navegadores compatíveis. Um ponto de selo é uma pequena marca no ícone instalado que indica que algo está esperando dentro do app.

Exemplo de Twitter com oito notificações e outro app mostrando um distintivo tipo bandeira.

É necessário chamar setAppBadge(count) no objeto navigator para definir um número de selo. Você pode fazer isso no contexto da janela ou do service worker quando souber que há uma atualização para alertar o usuário.

let unreadCount = 125;
navigator.setAppBadge(unreadCount);

Para limpar o selo, chame clearAppBadge() no mesmo objeto:

navigator.clearAppBadge();

Recursos