Por que non ves os cambios na túa web aínda que xa os publicamos

O xoves pasado un cliente que leva unha academia de idiomas online chamoume, case anoxado, dicindo que levaba tres días pedíndonos que cambiásemos o prezo dun curso na web e que seguía vendo o número antigo. Pedinlle que fixera Ctrl+Maiús+R no navegador. Vino cambiado ao instante. Colgou sen darme as grazas, cousa que entendo perfectamente.
Se non ves os cambios na túa web nada máis publicalos, case sempre é cuestión de caché: o navegador de quen visita a páxina, un proxy intermedio ou o noso propio servidor están a servir unha copia gardada que aínda non sabe que existe unha versión máis nova. O cambio leva no servidor desde o primeiro segundo, só que ninguén, entre o servidor e a pantalla, volveu pedilo.
Hai dúas cachés distintas metidas aí, e a xente mestúraas, con razón, porque desde fóra compórtanse igual: a web «non cambia». Está a do navegador de cada visitante, que non controlamos do todo pero si podemos indicarlle canto tempo fiarse dun ficheiro. E está a que serve o noso propio servidor antes de que a petición chegue a xerar a páxina, que esa si é enteiramente cousa nosa.
Os ficheiros con hash non dan ningún problema
Astro, ao facer o build, mete un hash do contido no nome de cada ficheiro CSS e JS, algo como index.a3f9c2.css. Se cambia unha coma do CSS, cambia o hash, cambia o nome do ficheiro, e o navegador pide un novo sen que ninguén lle diga nada. A eses ficheiros dicímoslles que se garden durante un ano enteiro (Cache-Control: public, max-age=31536000, immutable) e non pasa nada, porque se o contido cambia tamén cambia o nome. Ese truco aforroulnos bastantes chamadas cando o montamos, hai xa un par de anos.
O problema de verdade está no HTML, que non leva hash no nome: segue sendo /precios/index.html actualícese como se actualice o CSS que carga. Se lle dicimos ao navegador ou ao noso nginx que o garde durante, poñamos, unha hora, calquera cambio de prezo tarda ata unha hora en verse aínda que o servidor o teña listo desde o segundo un. E unha hora é moito tempo cando quen chama é un cliente cun curso a medio vender.
O que cambiamos despois da enésima chamada
Despois de varias chamadas parecidas á da academia de idiomas, deixamos de servir o HTML con caché longa. Agora sírvese con no-cache, must-revalidate: o navegador ten que preguntarlle ao servidor se hai algo novo cada vez, aínda que garde unha copia local para non descargala enteira se non cambiou nada. Os ficheiros con hash seguen cacheados un ano. É a combinación que corre no mesmo VPS do que falamos hai pouco, con nginx servindo os estáticos diante de Docker, o mesmo servidor ao que lle fixemos unha auditoría de seguridade que nos deixou bastante menos tranquilos do que esperabamos.
Segue habendo un caso que non resolvemos do todo ben.
Cando o cambio é nunha imaxe que non leva hash (un logo, unha foto de produto que o cliente nos manda co mesmo nome de ficheiro de sempre), aí si recomendamos, sen moito orgullo, o de toda a vida: refrescar con Ctrl+Maiús+R ou esperar un pouco. Poderiamos meter hash tamén nesas imaxes, pero complicaría o fluxo con clientes que suben as súas propias fotos por FTP, e de momento o custo non compensa o beneficio.
O que si aprendemos é a non dar por feito que «publicado» signifique «visible». Cando entregamos un cambio urxente avisamos ao cliente, antes de que chame, de que pode tardar un pouco en verse e por que. Custa un minuto explicalo e evita unha chamada das que empezan por «isto non funciona» cando en realidade si funciona: só que o seu navegador aínda non se decatou.