Etiquetas de entidad: qué son y cómo usarlas
Las etiquetas de entidad, también conocidas como ETags, son unos componentes muy útiles de HTTP que permiten a los sitios web ejecutarse más rápido mediante un almacenamiento en caché más eficiente de los recursos. Más concretamente, ayudan a distinguir varias representaciones de un mismo recurso, pero las ventajas que aportan en materia de rendimiento pueden acabar en saco roto si se utilizan o se implementan de formas incorrectas, lo cual pasa bastante a menudo. Optimizar la implementación de las etiquetas de entidad es una manera efectiva de acelerar un sitio web y reducir las llamadas al origen sin refactorizar el código ni revisar el contenido en exceso.
Como integrante del equipo de Solutions Engineering de Fastly (¡estamos buscando gente!</u>), me dedico a crear soluciones para clientes que utilizan la nube de informática en el edge flexible de Fastly. El caso es que, en mi día a día, a veces detecto lagunas en mis conocimientos de ciertos aspectos del protocolo de transferencia de hipertexto. Hace poco me di cuenta de que las ETags estaban entre ellos, así que voy a contar lo que he aprendido desde entonces. La explicación técnica se puede encontrar en RFC 9110</u>, donde se definen la sintaxis y la semántica del campo del encabezado de respuesta de las ETags, pero aconsejo seguir leyendo esta entrada, ya que voy a explicar qué son las etiquetas de entidad, cómo sacarles todo el partido y qué diferencias existen entre un uso adecuado e inadecuado de las mismas.
¿Qué es una etiqueta de entidad?
Una ETag es un campo del encabezado de respuesta de HTTP que contribuye al almacenamiento en caché facilitando la tarea de comprobar si un recurso ha cambiado sin necesidad de volver a descargarlo, proceso que se denomina «revalidación». Su cometido consiste en proporcionar la etiqueta de entidad de un recurso (es decir, su representación en un formato más corto), que suele ser el resultado de una función hash, como MD5 o SHA-1.
El mejor tipo de almacenamiento en caché es aquel en el que no hay peticiones de por medio, como cuando una respuesta se almacena de forma explícita en la caché del navegador mediante el campo de encabezado Cache-Control. En nuestro blog hay un artículo excelente sobre este tema</u>.
El segundo mejor tipo es aquel en el que sí se produce una petición, pero no hace falta un cuerpo de respuesta porque el recurso de destino no ha cambiado desde que el navegador lo recuperó por última vez. Aquí entran en juego las ETags.
El valor real de una etiqueta de entidad no se define por su especificación, sino que es cosa del servidor. Desde el punto de vista de Fastly, se trata de un valor opaco que se almacena pero que no intentamos analizar o interpretar de ninguna manera. El servidor de origen determina si lo que decimos que tenemos ha cambiado. En caso de no ser así, el origen envía una respuesta para informarnos de que podemos seguir usándolo.
Sin embargo, las ETags no son siempre la forma ideal de revalidar los recursos. Si sabemos cuándo se modificó un recurso por última vez y tenemos suficiente con una resolución inmediata, debemos utilizar en su lugar el campo del encabezado de respuesta Last-Modified. Esto significa que el servidor puede pedir que solo se le envíe el contenido si ha cambiado desde la fecha en la que lo recuperó por última vez. Realizar un seguimiento de la última fecha de modificación puede ser más sencillo que generar una etiqueta de entidad.
A modern CDN gives you huge improvements in caching, SEO, performance, conversions, & more.
Ejemplo práctico
Como leer la explicación técnica da un poco de pereza, vamos a verlo con un ejemplo práctico. Voy a omitir algunos campos de encabezado para facilitar la comprensión.
Aquí tenemos un ejemplo de la petición de un servidor para acceder a la página de inicio de Fastly:
> GET / HTTP/2
> Host: www.fastly.com
...
Y aquí tenemos la respuesta del servidor de Fastly con el cuerpo incluido:
< HTTP/2 200
< Cache-Control: max-age=0, must-revalidate
< Content-Length: 524653
< ETag: "ebeb4dbc1362d124452335a71286c21d"
...
Esta respuesta indica que el navegador debe revalidar la página antes de volver a utilizarla. Para ello, se realiza una petición con el campo de encabezado If-None-Match utilizando el valor de la ETag de la anterior respuesta. El nombre If-None-Match es un poco críptico en inglés, pero viene a significar que solo se debe enviar el cuerpo si la ETag es diferente de la utilizada. La próxima vez que el usuario final quiera abrir la página de Fastly, el navegador enviará una petición un poco distinta:
> GET / HTTP/2
> Host: www.fastly.com
> If-None-Match: "ebeb4dbc1362d124452335a71286c21d".
...
Si el servidor de Fastly decide que la página de inicio sigue teniendo la misma ETag que la indicada en la etiqueta If-None-Match, enviará una respuesta 304 Not Modified sin cuerpo, por lo que el navegador utilizará el cuerpo almacenado en caché al que había accedido en un primer momento:
< HTTP/2 304
...
La gran ventaja es que esta segunda vez no es necesario enviar el cuerpo a través de la red. Cuantos menos bytes se transfieran, mayor será el rendimiento del sitio web.
¿Cómo se utilizan las etiquetas de entidad?
Veamos cómo se utilizan las etiquetas de entidad en el vasto mundo de internet. HTTP Archive</u> examina con frecuencia los sitios web más visitados y registra todo tipo de información que podemos analizar. Vamos a centrarnos en el rastreador de dispositivos móviles 2023-02-01 de HTTP Archive, que examinó un total de 1 019 846 153 recursos. El campo del encabezado de respuesta de la ETag se utilizó en una de cada cuatro respuestas aproximadamente:
Aquí se pueden ver las 20 etiquetas de entidad más utilizadas. Cuanto mayor es su tamaño, mayor es su popularidad: Casi todas están formadas por números hexadecimales entre comillas y, en algunos casos, incluyen el prefijo W/ o el sufijo +gzip
:
Las ETags más comunes son objetos que se cargan en numerosos sitios web. En su mayor parte son plataformas publicitarias, aunque también están React 16.4.0</u>, React DOM 16.14.0</u> y Font Awesome 4.7.0</u>. Puede que no sean las últimas versiones de estas bibliotecas, pero son las más populares por ETag según el rastreo.
La función de una etiqueta de entidad es distinguir varias representaciones de un mismo recurso, lo cual podemos lograr de varias formas. Cuando un recurso tiene varias versiones, lo más sencillo es añadir el número de versión a la etiqueta de entidad.
¿Cuáles son las etiquetas de estas características más utilizadas? Parece que la mayoría de los recursos con versiones no cambian nunca o bien lo hacen muy a menudo, y buena muestra de ello es la poca presencia que tiene la versión 3.
¿Cómo se puede saber si el valor de una etiqueta de entidad de uso común se corresponde con una versión concreta de una biblioteca de tipos de letra? Una representación también se puede identificar mediante la asignación de un hash. Resulta que la representación en hexadecimal (128 bits en 32 caracteres) de la versión 4.7.0 del archivo fontawesome-webfont.woff2
mediante el algoritmo MD5 es af7ae505a9eed503f8b8e6982036873e
. Este método se utiliza en un buen número de servidores y sitios web, por lo que consigue colarse entre los 20 más utilizados.
¿Cuáles son los hashes que más se utilizan como etiquetas de entidad? Si nos fijamos en la longitud de las etiquetas de entidad y obviamos las comillas, vemos que MD5 y SHA-1 son los más habituales.
Puede que MD5 y SHA-1 se consideren inseguros para temas relacionados con el cifrado, pero cumplen su función a la hora de comprobar si un recurso ha experimentado algún cambio.
Si las longitudes de los hashes más utilizados son potencias de dos, ¿por qué hay tantos con una longitud de 37? Pues porque se trata de un hash MD5 con un prefijo +gzip
. Lo veremos a fondo más adelante.
Antes hemos dicho que algunas de las etiquetas de entidad más populares comienzan con el prefijo W/. Las etiquetas de entidad pueden ser validadores débiles o fuertes (estos últimos de forma predeterminada) y, si los datos cambian, un validador fuerte también cambia. El prefijo W/ designa un validador débil. Si los datos cambian, un validador débil puede cambiar o quedarse como está. La mayoría de las etiquetas de entidad son validadores fuertes:
Otra etiqueta de entidad muy utilizada es "95e1b50b0c179aefb47b5b211bb347b5+gzip
". Como su propio nombre indica, todas sus respuestas se comprimen con gzip. Al comprimir el cuerpo, el resultado es una representación diferente del mismo recurso, por lo que es de esperar que la etiqueta de entidad cambie.
Los sufijos más comunes son -gzip y -br
:
La representación Content-Type del recurso afecta al porcentaje que utiliza validadores débiles. Las versiones comprimidas tienen distintas representaciones, por lo que deben asociarse a un validador fuerte con un sufijo o a un validador débil.
Los tipos que se pueden comprimir, como CSS, JavaScript y SVG, suelen utilizar validadores débiles:
Otra etiqueta de entidad muy extendida es "1637097310169751
", que guarda un parecido más que razonable con un contador de segundos desde el comienzo de la época Unix. Su representación es 2021-11-16T21:15:10Z
, que con toda probabilidad equivale a la fecha y la hora en las que el recurso se modificó por última vez. Teniendo en cuenta que el recurso no parece cambiar muy a menudo, una buena alternativa sería utilizar el campo del encabezado de respuesta Last-Modified.
Prácticas recomendadas para las etiquetas de entidad
Ahora que ya sabemos cómo se utilizan las etiquetas de entidad en internet, veamos cómo sacarles el máximo partido.
Los recursos deben tener un validador, como Last-Modified o una ETag, para que los navegadores puedan revalidarlos.
Las etiquetas de entidad deben tener una sintaxis válida; es decir, estar entre comillas dobles y empezar por el prefijo W/, esto segundo de manera opcional.
Si un recurso está controlado únicamente por versión, la etiqueta de entidad debe ser fuerte e incluir el número de versión.
Si un recurso no está controlado únicamente por versión, la etiqueta de entidad debe ser fuerte e incluir un hash de su contenido.
Las distintas representaciones de un recurso, como los diferentes formatos de una misma imagen o la codificación de contenido comprimido, deben tener etiquetas individuales, que pueden ser etiquetas de entidad fuertes o débiles en función de lo que mejor se ajuste a cada caso.
¿Cómo no se deben utilizar las etiquetas de entidad?
Las etiquetas de entidad no siempre se usan correctamente en internet, y cuando esto ocurre, existe la posibilidad de que los usuarios vean información obsoleta en vez de contenidos al día.
En la imagen con palabras de distintos tamaños de arriba aparece OPTOUT
, que no es válida y carece de comillas dobles, entre las etiquetas de entidad más utilizadas. Pues bien, por cada una hay un servidor de anuncios mal configurado.
Hay muchas etiquetas de entidad formadas por palabras en inglés que no son válidas. Estas son mis favoritas:
ETag: $etagFile
ETag: abcdefg
ETag: custom
ETag: default
ETag: hash
ETag: himom
ETag: immutable
ETag: null
ETag: SAMEORIGIN
ETag: tag
ETag: undefined
ETag: Unkown
Tampoco podemos olvidarnos de las etiquetas de entidad que, a pesar de ser válidas, parecen generadas por un sistema de plantillas que no las ha sustituido correctamente:
ETag: "AssetsCalculatedEtagValue"
ETag: "CalculatedEtagValue"
ETag: "MyCalculatedEtagValue"
Como al menos una de ellas procede de código de ejemplo</u>, conviene recordar que siempre hay que asegurarse de que este código esté terminado antes de enviarlo a producción.
También es posible encontrar etiquetas de entidad con espacios, como "3/19/2017 6:35:34 PM". Los espacios no están admitidos.
Y también algunas con un validador débil por partida doble, como W/W/"49-FHKkWnYgBQtmkHTlg06OHZmoo5A. Esto tampoco está admitido.
Resumen
Ya sabemos todo lo que hay que saber acerca de las etiquetas de entidad y sus usos más adecuados. ¡Todo el mundo a validar sus representaciones!