Back home

La entrega front-end en la era de la publicación de alta frecuencia necesita rediseñar el almacenamiento en caché y la colaboración de compresión

A medida que los recursos se fragmentan cada vez más y las versiones se vuelven cada vez más frecuentes, a menudo no es la tasa de compresión lo primero que realmente se sale de control, sino el ritmo de liberación de las claves de caché, las versiones del diccionario y los costos de retorno al origen.

Una vez que los recursos front-end entren en un ritmo de lanzamiento de alta frecuencia, los problemas de rendimiento pronto ya no serán tan simples como “activar Brotli”. La primera pantalla se ralentiza, el tráfico de regreso al origen aumenta y la CPU del nodo perimetral tiembla. Superficialmente parece que la compresión no es lo suficientemente agresiva. Mirando más profundamente, a menudo son el almacenamiento en caché y la compresión los que se optimizan por separado y finalmente se socavan entre sí en el enlace de publicación.

Este tipo de problema generalmente no se expone en la primera versión. Al principio, el equipo solo veía algunas señales dispersas: un pequeño cambio provocaba una caída en la tasa de aciertos de los recursos estáticos, un aumento anormal en la compresión de borde de la CPU en vísperas de una promoción importante y el volumen de paquetes devueltos en la etapa de escala de grises no coincidía con el tráfico oficial. Si continúa comprobando, las pistas generalmente convergen en lo mismo: aunque el contenido del recurso solo ha cambiado un poco, la clave de caché, la división de fragmentos y la entrada comprimida se han convertido en un conjunto diferente de cosas, y la capa de transporte se ve obligada a asumir todo el costo nuevamente.

Hasta que el hash del recurso sea estable, los beneficios de la compresión son simplemente insostenibles.

Después de que los proyectos front-end se lanzan en paralelo con múltiples páginas, múltiples rutas y múltiples equipos, el aspecto que más fácilmente se pasa por alto es la estabilidad del nombre de los archivos. Siempre que la segmentación de fragmentos se desvíe ligeramente, incluso si el código comercial solo cambia la copia de un botón, el producto final también puede reescribir el hash de una serie de paquetes públicos. Lo que ve el sistema de almacenamiento en caché es un lote de objetos nuevos y lo que ve el sistema de compresión es un lote de entradas que aparecen por primera vez.

En este momento, no importa cuán alta sea la tasa de compresión, no puede evitar que la tasa de aciertos colapse. Los archivos antiguos todavía se encuentran en los nodos de borde y se han cambiado las claves de los archivos nuevos; el caché local del navegador no es completamente válido y la CDN tiene que volver a extraer la fuente, volver a comprimirla y redistribuirla. Un cambio de pequeña empresa se magnifica en trabajo repetido para todo el enlace de transmisión.

La acción realmente útil no suele ser seguir ajustando el nivel de compresión, sino controlar primero la estabilidad del producto liberado:

  • Las dependencias públicas se dividen en capas separadas para reducir los cambios comerciales y reunir paquetes básicos para cambiar el hash.
  • Evite mezclar cambios de alta frecuencia, como marcas de tiempo y números de compilación, directamente en el contenido del producto.
  • Deje que el código cercano a la misma ruta se divida en fragmentos estables tanto como sea posible en lugar de reorganizarlo cada vez que se compila.

Solo cuando se estabiliza la identidad del recurso se puede reutilizar continuamente el caché y los resultados de la compresión tienen valor acumulativo.

La conferencia de prensa de alta frecuencia reescribe el problema de compresión en un problema de versión de diccionario

A medida que los recursos se fragmentan cada vez más, Brotli o gzip de archivo único siguen siendo importantes, pero ya no lo son todo. El costo real comienza a desplazarse hacia piezas duplicadas: el código de tiempo de ejecución del marco, las plantillas de estilo, las declaraciones de tipo de interfaz, las capas de empaquetado generadas por los empaquetadores, a menudo son muy similares entre lotes de versiones. Con un ritmo de lanzamiento rápido, estos riffs se transferirán una y otra vez.

El problema es que el diccionario de compresión puede pasar fácilmente de una optimización a una interrupción si no se gestiona junto con la cadencia de lanzamiento. Si el diccionario se cambia con anticipación, el nuevo diccionario al que hace referencia la página anterior no coincidirá; el diccionario se corta en demasiados pedazos y el número de versiones que deben mantener los nodos de borde aumenta drásticamente; la actualización del diccionario no se sincroniza con el recurso en línea y los objetos que deberían haber sido afectados vuelven a la transmisión completa.

Este también es un cambio muy práctico en la entrega front-end reciente: diferentes equipos ya no pueden mantener las estrategias de almacenamiento en caché y los protocolos de compresión. Las versiones de recursos, las versiones de diccionario y los espacios de claves de caché son esencialmente el mismo problema de publicación.

Un enfoque jerárquico como el siguiente suele ser más estable que una “compresión fuerte unificada para todo el sitio”:

const policy = {
  immutableAssets: 'public, max-age=31536000, immutable',
  releaseManifest: 'public, max-age=60, stale-while-revalidate=30',
  sharedDictionary: 'versioned-by-release-train'
}

La clave no es la configuración en sí de estas tres líneas, sino las limitaciones que expresan: los recursos de ciclo de vida largo, la lista de ciclo de vida corto y la versión comprimida del diccionario deben evolucionar juntos de acuerdo con el mismo ritmo de lanzamiento.

La presión de volver a la fuente a menudo no es que el archivo sea demasiado grande, sino que el método de falla es demasiado aproximado.

Otro error de cálculo muy común es atribuir el aumento de ancho de banda directamente al peso de la página. Las páginas ciertamente son cada vez más pesadas, pero los amplificadores en línea más peligrosos suelen ser el camino a seguir.

Si limpia por directorio, prefijo o incluso todo el sitio cada vez que publica, la capa de caché perderá su memoria instantáneamente. En este momento, incluso si el tamaño del archivo no continúa creciendo, el valor máximo de retorno al origen aumentará por sí solo. Tan pronto como se devuelve la fuente, los bordes se recomprimen, los objetos se recalientan y se vuelve a descargar el navegador. La ventana de publicación cambiará de un pequeño cambio a una reubicación completa del sitio.

En este tipo de escenarios lo más valioso es el radio de fallo controlable:

  • Solo invalidar manifiestos, HTML y recursos mutables que realmente hayan cambiado.
  • Intente no purgar archivos estáticos con hash y entréguelos a nuevas referencias para un cambio natural.
  • Divida el lanzamiento en el orden de “primero cargar nuevos recursos, luego cortar referencias y luego reciclar recursos antiguos” en lugar de borrarlos todos a la vez.

Lo realmente sensible sobre el costo de transferencia no es sólo el tamaño del archivo, sino también cómo el sistema decide qué contenido debe recuperarse.

El límite aplicable se determina junto con la escala de recursos y la frecuencia de liberación.

Este conjunto de codiseño no es necesario para todos los sitios. Para proyectos con una pequeña cantidad de páginas estáticas, un pequeño paquete de recursos y una frecuencia de lanzamiento semanal o incluso mensual, el uso de nombres de archivos hash tradicionales más la precompresión de Brotli suele ser lo suficientemente estable.

El almacenamiento en caché y la compresión juntos se convierten rápidamente en una infraestructura de entrega una vez que se implementan estas características:

  • Publicado varias veces al día, con escala de grises, reversión o lanzamientos regionales.
  • El producto front-end es de gran tamaño, tiene muchas dependencias públicas y relaciones de fragmentos complejas.
  • CDN, almacenamiento de objetos, compresión perimetral y almacenamiento en caché del navegador participan simultáneamente en el enlace de transmisión.
  • El tráfico es tan alto que la tasa de aciertos de la caché y el valor máximo de retorno al origen reflejarán directamente el costo y la estabilidad.

Una vez que la entrega front-end entra en esta etapa, la compresión ya no consiste simplemente en “reducir el tamaño de los archivos” y el almacenamiento en caché ya no consiste simplemente en “almacenar más copias de contenido”. Lo que los dos deciden juntos es: para un cambio de pequeña empresa, si es solo enviar un fragmento más o si es necesario volver a ejecutar todo el enlace de transmisión. Cuanto más frecuentemente publiques, más cara se vuelve esta diferencia.

FAQ

What to read next

Related

Continue reading