Los sitios estáticos siguen activos mientras se vuelven a publicar
Volver a publicar un sitio estático en Mythex solía borrar primero los archivos en vivo y luego subir la nueva compilación, así que durante la subida algunos visitantes recibían una página 404 o una página cuyos scripts faltaban. Una subida fallida podía dejar el sitio vacío o a medio actualizar. Ahora la nueva compilación se escribe sobre la anterior, las páginas al final, y los restos se eliminan unos minutos después. Una segunda corrección hace que una nueva publicación se vea en segundos en lugar de en un minuto o, para archivos como un logotipo, hasta en un día.
Cómo se sirve un sitio estático
Un sitio estático es uno formado solo por archivos: páginas HTML, JavaScript, CSS e imágenes. Cuando lo publicas en Mythex, lo compilamos, subimos el resultado a almacenamiento de objetos en una carpeta de tu sitio y lo servimos a través de una red de borde: servidores cercanos a tus visitantes que obtienen los archivos del almacenamiento y guardan copias durante un tiempo. (Si esto te resulta nuevo, nuestra guía sobre qué es una CDN explica la idea.)
Había dos cosas mal: el orden en que una nueva publicación cambiaba los archivos y el tiempo que se conservaban las copias antiguas.
Problema 1: la subida vaciaba el sitio primero
Volver a publicar borraba todo lo que había en la carpeta del sitio y luego subía la nueva compilación. Durante todo el tiempo que duraba la subida (12 segundos para un sitio de 250 archivos en nuestra prueba local), un visitante cuya petición no estuviera ya en caché en el borde recibía un 404, o una página HTML cuyos scripts devolvían 404.
Una subida fallida era peor. La carpeta ya estaba vacía, y en una de las dos rutas de subida el nuevo index.html podía quedar colocado antes que el archivo que fallaba. Una publicación notificada como fallida podía dejar en vivo un sitio a medio nuevo.
La solución: sobrescribir, páginas al final, limpiar después
- No borrar primero. La nueva compilación se sube encima de la anterior.
- Recursos antes que páginas. Una página nombra los scripts y estilos que necesita, así que las páginas suben al final. Hasta que llegan las nuevas páginas, los visitantes reciben la página antigua, que nombra los recursos antiguos, que siguen ahí. Cuando llegan, los nuevos recursos que nombran ya están en su sitio.
- Eliminar los restos más tarde. Antes de la subida, listamos de qué está hecho el sitio. Tres minutos después de una subida correcta, se borra cualquier cosa de esa lista que la nueva compilación no haya reescrito. Tres minutos son más que los 60 segundos que una página podría estar en caché en el borde y en el navegador, así que un visitante que aún tenga la página antigua puede encontrar los recursos que nombra.
- En caso de duda, no borrar nada. Si falla el listado previo a la subida, no se poda nada. Los archivos sobrantes no hacen daño, y la siguiente publicación los limpia. Borrar sin saber qué había es como un sitio acaba vacío.
Una subida fallida ahora deja el sitio anterior exactamente como estaba.
Lo probamos de extremo a extremo en local, con el script de subida real, la ruta de subida real y el servicio de almacenamiento, y con visitantes que llegaban con la caché del borde en frío. Con el código antiguo, 55 de 91 visitas salieron mal durante una nueva publicación, y 61 de 92 durante una fallida. Con el código nuevo, 0 salieron mal en unas 3.500 visitas que cubrían ambas rutas de subida, una subida fallida y la publicación posterior, y se podaron exactamente los archivos sobrantes.
Problema 2: una nueva publicación tardaba demasiado en verse
Aun cuando la subida salía bien, los cambios tardaban en aparecer. El borde mantenía su copia de una página durante 60 segundos y de cualquier otro archivo durante un día, y decía a los navegadores que hicieran lo mismo. Los archivos con nombre fijo, como logo.png, una fuente o cualquier cosa de una carpeta public/, podían mostrar la versión antigua hasta un día después de una nueva publicación.
La solución: copias de archivos bajo la compilación
Cuando el borde pregunta a nuestra API dónde vive un sitio, la respuesta ahora incluye un marcador de compilación que cambia cada vez que se completa una publicación. El borde guarda sus copias bajo ese marcador. Por tanto, una publicación se convierte en un conjunto completamente nuevo de claves de caché en cuanto caduca la consulta de 30 segundos del borde. Las copias antiguas simplemente ya no se encuentran, así que el borde puede conservar copias durante un día sin servir nunca una que ya fue reemplazada por una publicación posterior.
Los navegadores reciben dos reglas distintas:
- La salida de compilación con hash, archivos como
assets/index-CzLcxDO8.jscuyo nombre cambia cada vez que cambia el contenido, se guarda en caché durante un año y se marca como inmutable. Bajo ese nombre nunca puede quedar desfasado. - Todo lo demás, es decir, páginas y archivos de nombre fijo como un logotipo, se marca como
no-cache, que significa «comprueba antes de usar». Si no cambió nada, la respuesta es un304 Not Modifieddiminuto sin cuerpo, ahora que respetamos la comprobaciónIf-None-Matchdel navegador.
Distinguir ambos casos requiere cuidado: un archivo copiado desde public/assets/ conserva su propio nombre, y poner assets/logo.png en caché durante un año fijaría el logotipo antiguo un año entero. Así que un archivo solo cuenta como con hash si está en una carpeta de salida de compilación y su nombre tiene un segmento que parece un hash, no una palabra corriente.
En local, la nueva página y el nuevo logotipo fueron visibles 6 segundos después de que la publicación entrara en vivo. Antes eran 60 segundos para la página y un día para el logotipo.
Dos correcciones menores por el camino
- Páginas en blanco con peticiones HEAD. Una petición
HEADpide las cabeceras de una página sin su cuerpo. Estábamos guardando en caché esas respuestas vacías, así que el siguiente visitante de esa página recibía una página en blanco. Las respuestasHEADya no se guardan en caché. - Una página real para «aquí no hay nada». Una dirección sin aplicación recibía antes un texto plano «Esta aplicación publicada está fuera de línea o el enlace no se encontró» con un código de error 502. Ahora recibe una página adecuada, «Aquí no hay ninguna aplicación», con estado 404 y un enlace de vuelta a Mythex para el propietario. Los dominios personalizados desconocidos reciben la misma página.
Lo que aprendimos
- El orden forma parte de la corrección. Los mismos archivos subidos en otro orden son la diferencia entre un sitio roto y uno que funciona.
- Borra tarde, y solo lo que conoces. Podar con un listado tomado antes de la subida es seguro; vaciar una carpeta y confiar en que la subida termine no lo es.
- Guarda en caché por versión, no por tiempo. Los tiempos de caducidad son una suposición sobre cuándo cambia el contenido. Una clave que cambia con la compilación es un hecho.
Relacionado: tu aplicación publicada sigue activa mientras la vuelves a publicar. Más sobre publicación en la documentación.