Imagem de introduĆ§Ć£o

Evitando armadilhas do Cache šŸ¤”

"NĆ£o tĆ” funcionando? Deve ser cache!", essa frase Ć© muito comum entre devs, mas sabia que configuraƧƵes mal feitas de cache realmente podem destruir sua aplicaĆ§Ć£o?

IntroduĆ§Ć£o

Neste artigo, vou compartilhar uma histĆ³ria real sobre como um erro de configuraĆ§Ć£o do Service Worker causou um loop infinito impediu que os usuĆ”rios recebessem atualizaƧƵes de novas versƵes da aplicaĆ§Ć£o e como resolvemos esse problema.

A histĆ³ria

Alguns anos atrĆ”s, em meados de 2017 (jĆ” faz tempo hein!), trabalhei numa aplicaĆ§Ć£o SPA (Single Page Application) que tava sendo convertido em um PWA (Progressive Web App) usando Service Worker, tecnologia que permite que aplicativos web sejam instalĆ”veis, funcionem offline e ofereƧam uma melhor experiĆŖncia de usuĆ”rio.

O processo foi bem tranquilo atƩ que percebemos dois erros cruciais:

  • Esquecemos de remover o index.html do cache do Service Worker
  • Esquecemos de remover o service-worker.js do cache do servidor

E ai a merda tava feita šŸ¤”

ConsequĆŖncias

Num primeiro momento nĆ£o percebemos erros, a aplicaĆ§Ć£o continuava funcionando normalmente, e os usuĆ”rios nĆ£o relataram problemas. Mas quando lanƧamos uma nova versĆ£o os problemas comeƧaram a aparecer.

UsuĆ”rios que jĆ” tinham a aplicaĆ§Ć£o instalada nĆ£o recebiam a nova versĆ£o. Eles continuavam usando a versĆ£o antiga mesmo depois de recarregar a pĆ”gina, jĆ” que o Service Worker estava servindo uma versĆ£o cacheada do index.html e o service-worker.js do servidor tambĆ©m estava cacheado, impedindo que a nova versĆ£o fosse baixada.

Isso porque SPAs (Single Page Applications) carregam o index.html uma Ćŗnica vez e, em seguida, usam JavaScript para atualizar o conteĆŗdo da pĆ”gina.

Como o index.html estava cacheado, os usuĆ”rios nĆ£o recebiam esses novos chunks de JavaScript e CSS, assim a aplicaĆ§Ć£o continuava funcionando com a versĆ£o antiga, pra sempre! šŸ˜±

Primeiras tentativas de soluĆ§Ć£o

A primeira coisa que tentamos foi invalidar o cache do Service Worker. No entanto, isso nĆ£o resolveu o problema, pois o index.html (que tambĆ©m chamava o Service Worker) ainda estava cacheado.

Isso porque Service Worker estava sempre servindo a versĆ£o cacheada do index.html, que chamava o Service Worker que por sua vez servia a versĆ£o cacheada do index.html, e assim por diante.

Isso criou um loop infinito que impediu que os usuĆ”rios recebessem atualizaƧƵes de novas versƵes da aplicaĆ§Ć£o šŸ¤”

Uma alternativa ā€œmanualā€ foi simplesmente pedir para os usuĆ”rios que entravam em contato reportando problemas limparem completamente o cache do navegador, mas isso nĆ£o era uma soluĆ§Ć£o escalĆ”vel e nem garantia que todos os usuĆ”rios fariam isso.

SoluĆ§Ć£o final

Depois de muita investigaĆ§Ć£o e analise, encontramos uma soluĆ§Ć£o que resolveu a maioria dos casos:

  • Interceptamos a chamada para o index.html no servidor
  • Injetamos um script para limpar completamente qualquer Service Worker
  • Adicionamos um novo Service Worker, desta vez configurado corretamente

Essa interceptaĆ§Ć£o foi feita no servidor, onde conseguimos adicionar um script que limpava o cache do Service Worker mas tambĆ©m poderia ser feita atravĆ©s de gerenciadores de scripts como o Google Tag Manager.

JĆ” o script que limpava o cache do Service Worker era simples:

if ('serviceWorker' in navigator) {
  navigator.serviceWorker.getRegistrations().then(function (registrations) {
    for (let registration of registrations) {
      registration.unregister();
    }
  });
}

Enfim a paz! šŸ•Š

ConclusĆ£o

Esta experiĆŖncia mostra o quanto Ć© importante tomar cuidado com o cache em aplicaƧƵes web. ConfiguraƧƵes mal feitas podem causar problemas graves, difĆ­ceis de diagnosticar e ainda mais difĆ­ceis de resolver.

Vale muito a pena ler artigos e documentaƧƵes sobre Service Worker e cache para evitar cair nas mesmas armadilhas como essa.

Indico fortemente a leitura do Guia de Service Worker e desse artigo sobre cache do CSS Wizardry para entender melhor como funciona o cache e como evitar problemas como esse.

Essa histĆ³ria foi contada em primeira mĆ£o no Xwitter