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 de descarga general mediante la optimización y compresión de los recursos restantes.

Compresión de datos 101

Una vez que hayas configurado tu sitio web para evitar descargar recursos sin usar, 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 de procesamiento previo para tipos de contenido específicos y optimizaciones específicas de recursos que requieren la entrada del desarrollador.

Para proporcionar el mejor rendimiento, se requiere una combinación de todas las siguientes técnicas:

  • La compresión es el proceso de codificar información con menos 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 una variedad de técnicas para lograr la mejor compresión.

El proceso de reducción del tamaño de los datos se denomina compresión de datos. Muchas personas han aportado algoritmos, técnicas y optimizaciones para mejorar el índice de compresión, la velocidad de compresión y la memoria requerida por varios algoritmos de compresión.

El análisis completo de la compresión de datos está mucho más allá del alcance de esta guía. Sin embargo, es importante comprender, en términos generales, cómo funciona la compresión y las técnicas que puedes utilizar para reducir el tamaño de varios elementos que requieren tus páginas.

Para ilustrar los principios centrales 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 mediante el prefijo "#". Las anotaciones no afectan el significado del mensaje ni sus comportamientos.
  2. Los mensajes pueden contener headers, que son pares clave-valor (separados por ":" en el ejemplo anterior) que aparecen al principio del mensaje.
  3. Los mensajes pueden tener cargas útiles de texto.

¿Qué se puede hacer para reducir el tamaño del mensaje anterior, que comienza en 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 manera eficiente. Por ejemplo, si sabes que todos los mensajes tienen “formato” y “fecha”, puedes convertirlos en ID enteros cortos y solo enviarlos. Sin embargo, como tal vez no sea así, te recomendamos que no lo hagas por ahora.
  3. La carga útil es solo de texto. Si bien no sabemos cuál es su contenido real (aparentemente, usa un "secret-cipher"), con solo mirar el texto podemos ver que hay mucha redundancia. Quizás, en lugar de enviar letras repetidas, puedas contar la cantidad de letras repetidas y codificarlas de manera más eficiente. 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 mensaje nuevo tiene 56 caracteres, lo que significa que comprimiste el mensaje original en un 72%. Se trata de una reducción significativa.

Este es un ejemplo 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 los que se ilustran en el ejemplo anterior y, en la Web, se pueden usar para reducir significativamente los tiempos de descarga de los recursos. Cuando se aplica compresión a recursos basados en texto, una página web puede dedicar menos tiempo a cargar recursos, por lo que los usuarios pueden 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 únicamente un algoritmo de compresión, 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 los humanos. Sin embargo, esa legibilidad no es necesaria para mantener la funcionalidad de ese código fuente en sitios web de producción y puede retrasar la carga de los recursos en la Web.

La reducción es un tipo de optimización específica del contenido que puede reducir significativamente el tamaño de los recursos entregados, y las optimizaciones se aplican mejor como parte del proceso de compilación e implementación. Por ejemplo, los agrupadores son un tipo de software de uso frecuente que puede reducir automáticamente los recursos 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 simplemente borrar datos arbitrarios. Sin embargo, en algunos contextos en los que tenemos conocimientos específicos del contenido sobre el formato de los datos y sus propiedades, es posible reducir significativamente el tamaño de la carga útil sin afectar su significado ni 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 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. Usa 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 constituye 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 notar que usamos una forma ineficiente de definir reglas para .awesome-container y contraer las dos declaraciones en una sin afectar ningún otro estilo, lo que ahorra más bytes. En un gran conjunto de reglas de CSS, quitar este tipo de redundancia puede generar, pero es posible que no sea algo que se pueda aplicar de forma agresiva, ya que los selectores se suelen duplicar en diferentes contextos, como dentro de las consultas de medios.
  • Los espacios y las pestañas son útiles 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 se puede aplicar de forma bastante agresiva, siempre que esos espacios o pestañas no sean necesarios para la presentación de la página. Por ejemplo, te recomendamos conservar los espacios en las ejecuciones de texto de un documento HTML, ya que garantizan la legibilidad del contenido que los usuarios realmente 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>

Después de aplicar los pasos anteriores, la página pasa de 516 a 204 caracteres, lo que representa un ahorro de alrededor del 60%. Es cierto que no es muy legible, pero no es necesario que sea para poder usarlo. Las prácticas de desarrollo moderno también te permiten mantener las versiones legibles y con formato correcto del código fuente separadas del código bien optimizado que envías a producción. En combinación con los mapas de fuentes, que proporcionan una representación legible de tu código de producción transformado, puedes solucionar errores en la producción con mayor facilidad, por lo que puedes tener una buena experiencia de desarrollador y optimizar el rendimiento para la experiencia del usuario.

En el ejemplo anterior, se ilustra un punto importante: un compresor de uso general, por ejemplo, uno diseñado para comprimir texto arbitrario, podría hacer un buen trabajo al comprimir la página del ejemplo anterior, pero nunca sabrá que debe quitar los comentarios, contraer reglas de CSS o decenas de otras optimizaciones específicas del contenido. Es por eso que el procesamiento previo, la reducción y otras optimizaciones contextuales son importantes.

De manera similar, las técnicas descritas anteriormente se pueden extender más allá de los recursos basados en texto. Las imágenes, los videos y otros tipos de contenido contienen sus propias formas de metadatos y varias cargas útiles. Por ejemplo, cada vez que tomas una foto con una cámara, el archivo suele incorporar mucha información adicional: configuración de la cámara, ubicación, etcétera. Según la aplicación, estos datos pueden ser fundamentales (por ejemplo, un sitio para compartir fotos) o pueden ser 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 resumen, como primer paso en la optimización de la eficiencia de tus elementos, crea un inventario de los diferentes tipos de contenido y considera qué tipos de optimizaciones específicas para el contenido puedes aplicar para reducir su tamaño. Luego, después de determinar cuáles son, automatiza las optimizaciones. Para ello, agrégalas a los pasos de compilación y lanzamiento a fin de garantizar que las optimizaciones se apliquen de manera coherente en cada nueva versión de producción.

Compresión de texto con algoritmos de compresión

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

  • gzip y Brotli son algoritmos de compresión de uso general que tienen un mejor rendimiento en recursos basados en texto: CSS, JavaScript, HTML.
  • Todos los navegadores modernos admiten la compresión gzip y Brotli, y anunciarán la compatibilidad con ambos en el encabezado de la solicitud HTTP Accept-Encoding.
  • El servidor debe estar configurado para habilitar la compresión. El software del servidor web a menudo permitirá que los módulos compriman los recursos basados en texto de forma predeterminada.
  • Tanto gzip como Brotli se pueden ajustar para mejorar el índice de compresión mediante el ajuste del nivel de compresión. Para gzip, la configuración de compresión varía de 1 a 9, donde 9 es la mejor. Para Brotli, este rango es de 0 a 11, donde 11 es el mejor. Sin embargo, los ajustes 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, la configuración en el medio del rango suele ofrecer la mejor compensación entre la proporción de compresión y la velocidad. Sin embargo, es posible realizar compresión estática, que ocurre cuando la respuesta se comprime de antemano 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 recursos de calificación. Las CDN también pueden administrar la compresión dinámica y estática, lo que te brinda un aspecto menos de la compresión por el que debes preocuparte.

gzip y Brotli son compresores comunes que se pueden aplicar a cualquier flujo de bytes. De forma interna, recuerdan parte del contenido examinado anteriormente de un archivo y, luego, intentan encontrar y reemplazar fragmentos de datos duplicados de manera eficiente.

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

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

Archivo Algoritmo Tamaño sin comprimir Tamaño comprimido Índice de compresión
angular-1.8.3.js Brotli 1346 KiB 256 KiB El 81%
angular-1.8.3.js gzip 1346 KiB 329 KiB El 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 El 73%
jquery-3.7.1.min.js Brotli 85 KiB 27 KiB El 68%
jquery-3.7.1.min.js gzip 85 KiB 30 KiB 65%
lodash-4.17.21.js Brotli 531 KiB 73 KiB 86%
lodash-4.17.21.js gzip 531 KiB 94 KiB 82%
lodash-4.17.21.min.js Brotli 71 KiB 23 KiB El 68%
lodash-4.17.21.min.js gzip 71 KiB 25 KiB 65%

En la tabla anterior, se muestra el ahorro que pueden proporcionar Brotli y la compresión gzip para algunas bibliotecas de JavaScript conocidas. Los ahorros varían entre un 65% y un 86%, según el archivo y el algoritmo. A modo de referencia, se aplicó el nivel máximo de compresión a cada archivo para Brotli y gzip. Siempre que sea posible, es preferible usar 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 lo aprovecha, estás desaprovechando una gran oportunidad de mejorar el rendimiento de los usuarios. Afortunadamente, muchos servidores web proporcionan configuraciones predeterminadas que habilitan esta importante optimización, y las CDN, en particular, son muy eficaces para implementarlas, de modo que se equilibran la velocidad y la proporción de la compresión.

Una forma rápida de ver la compresión en acción es abrir las Herramientas para desarrolladores de Chrome, abrir el panel Red, cargar una página que desees y observar la parte inferior del panel de red.

Lectura de Herramientas para desarrolladores del tamaño real frente al de transferencia.
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 puede ver en el panel de red de las Herramientas para desarrolladores de Chrome.

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

  • 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 del recurso de todas las solicitudes. Esto refleja el tamaño de los recursos de la página después de que se descomprimen.

Efectos en las Métricas web esenciales

Las mejoras en el rendimiento no se pueden medir, a menos que haya métricas que reflejen esas mejoras. La iniciativa de Métricas web esenciales existe para crear y dar a conocer las métricas que reflejan la experiencia real del usuario. Esto contrasta con las métricas (como el tiempo de carga simple de la página, por ejemplo) que no se traducen claramente en la calidad de la experiencia del usuario.

Cuando aplicas las optimizaciones descritas 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, estos son algunos casos en los que aplicar esas optimizaciones puede mejorar las Métricas web esenciales de tu sitio web:

  • Los recursos HTML que están reducidos y comprimidos pueden mejorar la carga de ese HTML y la visibilidad de sus subrecursos y, por lo tanto, mejorar su carga. Esto puede ser beneficioso para el Largest Contentful Paint (LCP) de una página. Si bien se pueden usar sugerencias de recursos, como rel="preload", para modificar la visibilidad de los recursos, usar demasiadas puede causar problemas de contención de ancho de banda. Si te aseguras de que la respuesta HTML para una solicitud de navegación esté comprimida, el escáner de precarga puede descubrir los recursos dentro de ella lo antes posible.
  • Algunos candidatos de LCP también se pueden cargar antes usando la compresión. Por ejemplo, a las imágenes SVG que son candidatas para LCP, se puede reducir el tiempo de carga de los 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 mediante 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 para LCP. Las técnicas que se describen en esta guía dependen 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 tiempos de carga de recursos), reducir y comprimir tu CSS reduce el tiempo de carga, lo que significa que la renderización de posibles nodos de texto LCP puede ocurrir antes.

Conclusión

La forma de optimizar la codificación y la transferencia de elementos basados en texto es un concepto de rendimiento del modelo de referencia, pero 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 automaticen. En el caso de la reducción, usa un agrupador para aplicar la reducción a los recursos aptos. Asegúrate de que la configuración del servidor web admita la compresión, pero, más que eso, usa la compresión más eficaz disponible. Con el objetivo de que esto sea lo más trivial posible, usa CDN para automatizar la compresión, ya que no solo pueden comprimir los recursos por ti, sino que también lo hacen muy rápido.

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