Service worker para um app 100% no navegador: as 4 regras de cache que eu usaria de novo
Fiz um app web que funciona sem backend e continua abrindo offline depois da primeira visita. Os dados ficam no próprio navegador (IndexedDB para os documentos, localStorage para preferências pequenas). O que deu mais trabalho não foi o app, foi o service worker. Ficaram quatro regras:
1. Asset versionado = cache first, sem medo.
Todo JS/CSS vai com ?v=<versão>. Se a URL muda a cada deploy, o arquivo em cache nunca fica velho, então pode servir direto do cache.
2. A página (navigate) = network first, cache como reserva.
O HTML não tem versão na URL. Se servir do cache primeiro, o usuário fica preso numa versão antiga. Então: tenta a rede, guarda a cópia boa, e só cai no cache quando está offline. Cada página fica salva com a própria URL; se não tiver cópia, cai na página principal do app.
3. Dado vivo nunca entra no cache.
Endpoints .php e um rates.json (câmbio) passam direto, sem respondWith. Servir câmbio de três semanas atrás como se fosse de hoje é pior do que não mostrar nada.
4. O nome do cache leva a versão, e o activate apaga os antigos.
caches.keys() → filtra pelo prefixo do app → apaga tudo que não é a versão atual → clients.claim(). Sem isso, cada deploy deixa um cache inteiro esquecido no disco do usuário.
Dois detalhes que não são do service worker mas mordem igual:
- Formatação de número e moeda:
Intl.NumberFormatcom o locale do documento, não do navegador. Um documento em alemão aberto num navegador em português precisa sair1.234,56 €, não€ 1,234.56. - PDF:
window.print()com um CSS@media printbem feito resolve sem biblioteca de PDF e sem mandar nada para servidor.
Alguém aqui usa Workbox ou prefere escrever o service worker na mão como eu? Queria entender em que ponto a biblioteca começa a valer a pena.