Optimiza la codificación y el tamaño de transferencia de los recursos de texto

Después de eliminar las descargas de recursos innecesarias, lo mejor que puedes hacer para mejorar la velocidad de carga de la página es minimizar el tamaño general de las descargas optimizando y comprimiendo los recursos restantes.

Introducción a la compresión de datos

Una vez que hayas configurado tu sitio web para evitar la descarga de recursos no utilizados, el siguiente paso es comprimir los recursos aptos restantes que el navegador debe descargar. Según el tipo de recurso (texto, imágenes, fuentes, etc.), existen muchas técnicas diferentes para elegir: herramientas genéricas que se pueden habilitar en el servidor web, optimizaciones previas al procesamiento para tipos de contenido específicos y optimizaciones específicas para los recursos que requieren la intervención del desarrollador.

Para proporcionar el mejor rendimiento, se debe combinar todas las siguientes técnicas:

  • La compresión es el proceso de codificación de información mediante el uso de pocos bits.
  • La eliminación de datos innecesarios siempre proporciona los mejores resultados.
  • Existe una gran cantidad de técnicas y algoritmos de compresión diferentes.
  • Necesitarás diferentes técnicas para lograr la mejor compresión.

El proceso de reducción del tamaño de los datos se conoce como compresión de datos. Muchas personas han dedicado toda su carrera a trabajar en algoritmos, técnicas y optimizaciones para mejorar las relaciones de compresión, la velocidad de compresión y la memoria que requieren varios algoritmos de compresión.

El tratamiento de la compresión de datos en detalle está fuera del alcance de esta guía. Sin embargo, es importante comprender en profundidad el funcionamiento de la compresión y las técnicas con las que cuentas para reducir el tamaño de varios recursos que tus páginas necesitan.

Para ilustrar los principios fundamentales de estas técnicas, considera el proceso de optimización de un formato de mensaje de texto simple que se inventó para este ejemplo:

# Below is a secret message, which consists of a set of headers in
# key-value format followed by a newline and the encrypted message.
format: secret-cipher
date: 08/25/16
AAAZZBBBBEEEMMM EEETTTAAA
  1. Los mensajes pueden contener anotaciones arbitrarias, a veces denominadas comentarios, que se indican con el prefijo “#”. Las anotaciones no afectan el significado del mensaje ni sus comportamientos.
  2. Los mensajes pueden contener encabezados, que son pares clave-valor (separados por ":" en el ejemplo anterior) que aparecen al comienzo del mensaje.
  3. Los mensajes pueden presentar cargas útiles de texto.

¿Qué se puede hacer para reducir el tamaño del mensaje anterior, que comienza con 200 caracteres?

  1. El comentario es interesante, pero no afecta el significado del mensaje. Elimínalo cuando transmites el mensaje.
  2. Existen buenas técnicas para codificar encabezados de forma eficaz. Por ejemplo, si sabes que todos los mensajes tienen "formato" y "fecha", podrías convertirlos en IDs enteros cortos y enviar solo esos ID. Sin embargo, tal vez no sea cierto, por lo que es mejor dejarlo así por ahora.
  3. La carga útil es solo texto. Si bien no sabemos cuál es su contenido en realidad (aparentemente, usa un "secret-cipher"), con solo mirar el texto podemos ver que hay mucha redundancia. Quizás, en lugar de enviar letras repetidas, podrías contar la cantidad de letras repetidas y codificarlas de forma más eficaz. Por ejemplo, "AAA" se convierte en "3A", que representa una secuencia de tres A.

La combinación de estas técnicas produce el siguiente resultado:

format: secret-cipher
date: 08/25/16
3A2Z4B3E3M 3E3T3A

El nuevo mensaje tiene 56 caracteres. Esto significa que has comprimido el mensaje original en un 72%. ¡Esa es una reducción significativa!

Este es un ejemplo de juguete de cómo los algoritmos de compresión pueden ser eficaces para reducir el tamaño de transferencia de los recursos basados en texto. En la práctica, los algoritmos de compresión son mucho más sofisticados que lo que muestra el ejemplo anterior y, en la Web, se pueden usar para reducir de forma significativa los tiempos de descarga de los recursos. Cuando se aplica compresión a los recursos basados en texto, una página web puede dedicar menos tiempo a cargar recursos, de modo que los usuarios puedan ver los efectos de esos recursos antes de lo que lo harían sin compresión.

Reducción: procesamiento previo y optimizaciones específicas del contexto

La primera técnica que se analiza aquí es la minificación. Si bien la reducción no es un algoritmo de compresión estricto, es una forma de quitar los caracteres innecesarios y redundantes que se usan en el código fuente para que los recursos sean más legibles para las personas. Sin embargo, esa legibilidad no es necesaria para mantener la funcionalidad de ese código fuente en los sitios web de producción y puede retrasar la carga de recursos en la Web.

La reducción es un tipo de optimización de contenido específico que puede reducir de forma significativa el tamaño de los recursos entregados, y las optimizaciones se aplican mejor como parte del proceso de compilación y, luego, de implementación. Por ejemplo, los agrupadores son un tipo de software de uso frecuente que puede reducir los recursos automáticamente justo antes de la implementación de un nuevo código de producción en un sitio web.

La mejor manera de comprimir datos redundantes o innecesarios es eliminarlos. Sin embargo, no puedes borrar datos arbitrarios. Sin embargo, en algunos contextos en los que podemos conocer el formato de los datos del contenido y sus propiedades en general, se puede reducir notablemente el tamaño de la carga útil sin afectar su significado o sus capacidades reales.

<html>
  <head>
    <style>
      /* awesome-container is only used on the landing page */
      .awesome-container {
        font-size: 120%;
      }

      .awesome-container {
        width: 50%;
      }
    </style>
  </head>
  <body>
    <!-- awesome container content: START -->
    <div>
      This is my awesome container, and it is <em>so</em> awesome.
    </div>
    <!-- awesome container content: END -->
    <script>
      awesomeAnalytics(); // Beacon conversion metrics
    </script>
  </body>
</html>

Considera el fragmento de HTML anterior y los tres tipos de contenido diferentes que contiene:

  1. Lenguaje de marcado HTML.
  2. CSS para personalizar la presentación de una página.
  3. JavaScript para potenciar las interacciones y otras funciones avanzadas de la página

Cada uno de estos tipos de contenido tiene diferentes reglas para lo que conforma el contenido válido, diferentes reglas para especificar comentarios, etcétera. Sin embargo, la pregunta que queda es "¿Cómo se puede reducir el tamaño de esta página?".

  • Los comentarios de código son el mejor amigo del desarrollador, pero el navegador no los necesita. Quitar los comentarios de CSS (/* ... */), HTML (<!-- ... -->) y JavaScript (// ...) reduce el tamaño de transferencia total de la página y sus subrecursos.
  • Un compresor de CSS “inteligente” podría detectar que usamos una técnica ineficaz para definir reglas de .awesome-container y contraer las dos declaraciones para formar una sin afectar otros estilos, con lo cual se liberarán más bytes. En un gran conjunto de reglas de CSS, quitar este tipo de redundancia puede ser significativo, pero es posible que no sea algo que se pueda aplicar de manera agresiva, ya que los selectores a menudo están duplicados en diferentes contextos, como dentro de las consultas de medios.
  • Los espacios y las pestañas son servicios para desarrolladores en HTML, CSS y JavaScript. Un compresor adicional podría quitar todas las pestañas y los espacios. A diferencia de otras técnicas de anulación de duplicación, este tipo de optimización puede aplicarse de manera bastante agresiva, siempre y cuando esos espacios o pestañas no sean necesarios para la presentación de la página. Por ejemplo, te recomendamos conservar los espacios dentro de ejecuciones de texto en un documento HTML, ya que garantizan la legibilidad del contenido que los usuarios verán.
<html><head><style>.awesome-container{font-size:120%;width:50%}</style></head><body><div>This is my awesome container, and it is <em>so</em> awesome.</div><script>awesomeAnalytics()</script></body></html>

Una vez aplicados los pasos anteriores, la página pasa de 516 a 204 caracteres, lo que representa un ahorro de aproximadamente el 60%. Es cierto que no es muy legible, pero no es necesario que lo sea para que se pueda usar. Las prácticas de desarrollo modernas también te permiten mantener las versiones legibles y con buen formato de tu código fuente separadas del código bien optimizado que envías a producción. Combinado con los mapas de origen, que proporcionan una representación legible de tu código de producción transformado, te permiten solucionar problemas de errores en producción con mayor facilidad. Puedes tener una buena experiencia de desarrollador y, al mismo tiempo, optimizar el rendimiento en aras de la experiencia del usuario.

El ejemplo anterior ilustra un punto importante: un compresor de uso general, por ejemplo, uno diseñado para comprimir texto arbitrario, podría hacer un buen trabajo comprimiendo la página del ejemplo anterior, pero nunca sabría quitar los comentarios, contraer las reglas de CSS ni realizar docenas de otras optimizaciones específicas del contenido. Por eso, el procesamiento previo, la reducción y otras optimizaciones adaptadas al contexto son importantes.

De igual manera, las técnicas anteriores se pueden extender más allá de los recursos basados en texto. Las imágenes, los videos y otros tipos de contenido tienen sus propias formas de metadatos y diferentes cargas útiles. Por ejemplo, cada vez que sacas una foto con una cámara, su archivo suele incorporar mucha información adicional: configuración de la cámara, ubicación, etc. Según tu aplicación, estos datos pueden ser críticos (por ejemplo, un sitio para compartir fotos) o completamente inútiles. Debes considerar si vale la pena quitarlo. En la práctica, estos metadatos pueden sumar decenas de kilobytes por cada imagen.

En pocas palabras, como primer paso en la optimización de la eficiencia de tus recursos, crea un inventario de los diferentes tipos de contenidos y considera las optimizaciones de contenido que puedes aplicar para reducir su tamaño. Luego, una vez que hayas determinado cuáles son, automatiza esas optimizaciones agregándolas a los pasos de compilación y lanzamiento para garantizar que las optimizaciones se apliquen de manera coherente en cada versión nueva en producción.

Compresión de texto con algoritmos de compresión

El siguiente paso para reducir el tamaño de los recursos basados en texto es aplicarles un algoritmo de compresión. Esto va un paso más allá, ya que busca de manera agresiva patrones repetibles en cargas útiles basadas en texto antes de enviarlos al usuario, y los descomprime una vez que llegan al navegador del usuario. El resultado es una reducción adicional y significativa de esos recursos, y tiempos de descarga más rápidos.

  • gzip y Brotli son algoritmos de compresión de uso general que funcionan mejor en recursos basados en texto: CSS, JavaScript y HTML.
  • Todos los navegadores modernos admiten la compresión gzip y Brotli, y anuncian la compatibilidad con ambos en el encabezado de solicitud HTTP Accept-Encoding.
  • Tu servidor debe estar configurado para habilitar la compresión. El software del servidor web a menudo habilitará los módulos para comprimir los recursos basados en texto de forma predeterminada.
  • Tanto gzip como Brotli se pueden ajustar para mejorar las relaciones de compresión ajustando el nivel de compresión. Para gzip, la configuración de compresión varía de 1 a 9, siendo 9 la mejor. Para Brotli, este rango es de 0 a 11, y 11 es el mejor. Sin embargo, los parámetros de configuración de compresión más altos requieren más tiempo. En el caso de los recursos que se comprimen de forma dinámica (es decir, en el momento de la solicitud), los parámetros de configuración en el medio del rango suelen ofrecer la mejor compensación entre la relación de compresión y la velocidad. Sin embargo, es posible la compresión estática, que es cuando la respuesta se comprime con anticipación y, por lo tanto, puede usar la configuración de compresión más agresiva disponible para cada algoritmo de compresión.
  • Por lo general, las redes de distribución de contenidos (CDN) ofrecen compresión automática de los recursos que cumplen con los requisitos. Las CDN también pueden administrar la compresión dinámica y estática por ti, lo que te permite preocuparte por un aspecto menos de la compresión.

gzip y Brotli son compresores comunes que se pueden aplicar a cualquier flujo de bytes. De forma interna, recuerdan algunos de los contenidos de un archivo que se examinaron con anterioridad y, luego, intentan buscar y reemplazar fragmentos de datos duplicados de manera eficiente.

En la práctica, tanto gzip como Brotli ofrecen el mejor rendimiento en el contenido basado en texto y, a menudo, alcanzan tasas de compresión de hasta el 70% o el 90% para archivos más grandes. Sin embargo, ejecutar estos recursos de algoritmos que ya están comprimidos con algoritmos alternativos, como la mayoría de los formatos de imagen que usan técnicas de compresión con o sin pérdida, no ofrece una mejora significativa.

Todos los navegadores modernos anuncian compatibilidad con gzip y Brotli en el encabezado de solicitud HTTP Accept-Encoding. Sin embargo, es responsabilidad del proveedor de hosting garantizar que el servidor web esté configurado correctamente para proporcionar el recurso comprimido cuando el cliente lo solicite.

Archivo Algoritmo Tamaño sin comprimir Tamaño comprimido Índice de compresión
angular-1.8.3.js Brotli 1,346 KiB 256 KiB El 81%
angular-1.8.3.js gzip 1,346 KiB 329 KiB 76%
angular-1.8.3.min.js Brotli 173 KiB 53 KiB El 69%
angular-1.8.3.min.js gzip 173 KiB 60 KiB 65%
jquery-3.7.1.js Brotli 302 KiB 69 KiB El 77%
jquery-3.7.1.js gzip 302 KiB 83 KiB 73%
jquery-3.7.1.min.js Brotli 85 KiB 27 KiB 68%
jquery-3.7.1.min.js gzip 85 KiB 30 KiB 65%
lodash-4.17.21.js Brótli 531 KiB 73 KiB 86%
lodash-4.17.21.js gzip 531 KiB 94 KiB 82%
lodash-4.17.21.min.js Brótli 71 KiB 23 KiB 68%
lodash-4.17.21.min.js gzip 71 KiB 25 KiB 65%

En la tabla anterior, se muestran los ahorros que pueden proporcionar la compresión Brotli y gzip para algunas bibliotecas de JavaScript conocidas. Los ahorros varían entre el 65% y el 86%, según el archivo y el algoritmo. A modo de referencia, se aplicó el nivel de compresión máximo a cada archivo para Brotli y gzip. Siempre que sea posible, prefiere Brotli en lugar de gzip.

Habilitar la compresión es una de las optimizaciones más simples y eficaces que se pueden implementar. Si tu sitio web no aprovecha esta función, te estás perdiendo una gran oportunidad para mejorar el rendimiento de tus usuarios. Por suerte, muchos servidores web proporcionan configuraciones predeterminadas que habilitan esta optimización importante, y las CDN, en particular, son muy eficaces para implementarla de una manera que equilibre la velocidad y la proporción de compresión.

Una forma rápida de ver la compresión en acción es abrir Chrome DevTools, abrir el panel Network, cargar la página que elijas y observar la parte inferior del panel de red.

Lectura de DevTools del tamaño real en comparación con el de transferencia.
Una representación del tamaño de transferencia (es decir, comprimido) de todos los recursos de la página en comparación con su tamaño real, como se visualiza en el panel de red de Chrome DevTools.

Al igual que en la imagen anterior, deberías ver un desglose de lo siguiente:

  • Es la cantidad de solicitudes, que es la cantidad de recursos cargados para la página.
  • El tamaño de transferencia de todas las solicitudes. Esto refleja la eficacia de la compresión aplicada a cualquiera de los recursos de una página.
  • El tamaño de los recursos de todas las solicitudes. Esto refleja el tamaño de los recursos de la página después de que se descomprimieron.

Efectos en las Métricas web esenciales

No se pueden medir las mejoras en el rendimiento, a menos que haya métricas que las reflejen. La iniciativa Métricas web esenciales existe para crear y aumentar la conciencia sobre las métricas que reflejan la experiencia real del usuario. Esto contrasta con las métricas, como el tiempo de carga de la página, que no se traducen claramente en la calidad de la experiencia del usuario.

Cuando aplicas las optimizaciones que se describen en esta guía a los recursos de tu sitio web, los efectos en las métricas web esenciales pueden variar según los recursos optimizados y las métricas involucradas. Sin embargo, estas son algunas instancias en las que la aplicación de estas optimizaciones puede mejorar las Métricas web esenciales de tu sitio web:

  • Los recursos HTML que se reducen y comprimen pueden mejorar la carga de ese HTML, la visibilidad de sus subrecursos y, por lo tanto, mejorar su carga. Esto puede ser beneficioso para el Procesamiento de imagen con contenido más grande (LCP) de una página. Si bien las sugerencias de recursos, como rel="preload", se pueden usar para afectar la visibilidad de los recursos, usar demasiadas de ellas puede causar problemas con la contención de ancho de banda. Si te aseguras de que la respuesta HTML de una solicitud de navegación esté comprimida, el escáner de precarga podrá detectar los recursos que contiene lo antes posible.
  • Algunos candidatos de LCP también se pueden cargar antes con la compresión. Por ejemplo, las imágenes SVG que son candidatas a LCP pueden reducir su duración de carga de recursos mediante la compresión basada en texto. Esto es diferente de las optimizaciones que harías en otros tipos de imágenes, que se comprimen de forma intrínseca a través de otros métodos de compresión, como la forma en que las imágenes JPEG usan la compresión con pérdida.
  • Además, los nodos de texto también pueden ser candidatos de LCP. La forma en que se usan las técnicas descritas en esta guía depende de si usas una fuente web para el texto en tus páginas web. Si usas una fuente web, se aplican las prácticas recomendadas para la optimización de fuentes web. Sin embargo, si no usas fuentes web, sino fuentes del sistema que se muestran sin incurrir en ninguna duración de carga de recursos, la reducción y compresión de tu CSS reduce esta duración, lo que significa que la renderización de posibles nodos de texto de LCP puede ocurrir antes.

Conclusión

La forma en que optimizas la codificación y la transferencia de recursos basados en texto es un concepto de rendimiento de referencia, pero es uno que tiene un gran impacto. Asegúrate de hacer todo lo posible para garantizar que los recursos aptos para la reducción y la compresión se beneficien de esas optimizaciones.

Lo más importante es que te asegures de que estos procesos se estén automatizados. Para la reducción, usa un empaquetador para aplicar la reducción a los recursos aptos. Asegúrate de que la configuración de tu servidor web admita la compresión, pero, además, usa la compresión más eficaz disponible. Para que esto sea lo más sencillo posible, usa CDN para automatizar la compresión, ya que no solo pueden comprimir los recursos por ti, sino que también pueden hacerlo muy rápido.

Si unes estos conceptos de rendimiento de referencia en la arquitectura de tu sitio web, podrás asegurarte de que tus esfuerzos de optimización del rendimiento estén en buenas condiciones y que las optimizaciones posteriores puedan basarse en una base sólida de prácticas recomendadas de referencia.