en Optimización

Usar ETags para mejorar la performance

Este es mi primer artículo en el blog de los que hacemos minube. Estaba dudando en escribir porque no sabía qué podía aportar que les pudiera servir. Y dándole vueltas a la cabeza me acordé de los protocolos.. y más concretamente del HTTP. Así que hoy les voy a contar un poco acerca de las ETags. Creo recordar que entre las recomendaciones de Google, el uso de ETags está bien visto, porque nos habla de un sitio optimizado. Pero vamos al tema…

ETag. ¿eso con qué se come?

Un ETag no es más que parte de la información que se transmite dentro de las cabeceras (If-None-Match) de las solicitudes de HTTP. Básicamente sirve para indicarle al servidor web qué versión de una página (documento, archivo, etc) tenemos almacenada localmente, para que éste determine si ha cambiado y nos mande nuevamente la página. Es decir. La primera vez que visitamos una página -y si tenemos activada la caché- nuestro navegador la almacena localmente junto a algunos de los recursos adjuntos en dicha página. Para simplificar el concepto voy a ejemplificar con una página como «un todo», pero el concepto se aplica a cada request que hacemos. Cuando el servidor nos responde con la página nos envía una suma de comprobación o un código identificativo de la versión del documento en cuestión. De esta manera, la segunda vez que pidamos dicho documento, nuestro navegador (o User Agent en general), debería enviar dicho código dentro de las cabeceras. El servidor se encargará de determinar si el documento ha cambiado o si es el mismo. Si no ha cambiado nos devolverá un 304 (Not Modified), en caso contrario nos dará la versión más reciente del documento con su nuevo y respectivo código «de versión», por llamarle de alguna manera.

Cuando solicitamos un documento por primera vez, el servidor nos devuelve una cabecera como esta:

ETag: "64233457696a7c876b7e"

Y cuando la solicitamos por segunda vez, nosotros enviamos esta cabecera:

If-None-Match: "64233457696a7c876b7e"

Como no ha cambiado la suma el servidor nos devuelve un 304.

¿Y eso cómo me beneficia?

Si aún no te estás frotando las manos deberías empezar a hacerlo. Básicamente porque la implementación de los ETags nos permite ahorrar ancho de banda, tiempos de generación de páginas, consultas, etc etc etc. Está claro que esto es hilar bastante fino, porque también podemos utilizar cachés desde el lado del servidor, pero no es exactamente lo mismo.

Supongamos que tenemos una web de recomendación de productos, donde además de la ficha del producto, tenemos los comentarios de los usuarios, fotos, hojas de estilo, etc. Primero que nada tenemos el tiempo de generación de la página y las consultas a la base de datos. Por más de que sean querys livianas, por más de que la página no tenga mucha lógica interna, sigue siendo un instante de carga para el servidor. ¡Y nos lo podemos ahorrar!. Además, también tenemos el ancho de banda de volver a enviar la página, las fotos, las hojas de estilo, los archivos de javascript, etc. Si fuéramos capaces de aplicar las ETags a todos estos documentos, nos encontraríamos con el siguiente panorama:

– La primer petición sería normal, con su tiempo de generación, con su gasto de CPU, memoria, ancho de banda, etc. O podemos enviar una página cacheada desde el servidor. Aún así tenemos gasto de ancho de banda.

– Pero si esta página, por algún motivo es muy visitada por el mismo usuario, a la segunda petición el servidor le enviaría cabeceras 304 y el navegador automáticamente nos mostraría la versión almacenada en local.

Imagínate las posibilidades!

¡Me encanta! pero, ¿cómo lo aplico a mi sitio?

Lo cierto es que para poder aplicar esto, nuestro servidor web debe aceptar el manejo de los ETags. Afortunadamente los servidores serios y robustos como puede ser Apache sí lo permiten y son muy fácilmente configurables.

Esto nos serviría si tenemos contenido estático. Pero si tenemos contenido generado dinámicamente, muchas veces el servidor no es muy eficiente a la hora de determinar los cambios, por lo que podemos hacerlo a mano. Les voy a poner un ejemplo en PHP:

– Supongamos que tenemos la página http://misitio.com/noticias/munix-gana-el-euromillones-1090.html y que esta está generada dinámicamente con PHP y consultas MySQL. Esta página acepta comentarios de los usuarios y, por tanto, es susceptible de permanecer sin cambios, o tenerlos al recibir un comentario. Este ejemplo nos vale para aplicar los ETags. Para esto, añadimos el siguiente header:

$etag = md5 ($_SERVER[‘REQUEST_URI’] . $last_modification); //Donde $last_modification es la fecha del último comentario, por ejemplo. Esto nos permite controlar la temporalidad.

if (trim($_SERVER[‘HTTP_IF_NONE_MATCH’]) == $etag) {

header(«HTTP/1.1 304 Not Modified»);

exit;

}else{

header(«Etag: $etag»);

}

Con este sencillo código lo que hacemos es enviar la cabecera del ETag la primera vez o cuando no haya coincidencia, y a las siguientes que no haya cambiado el contenido mandamos el 304.

Está claro que esta solución no es válida para todos los proyectos, pero seguramente te dará una noción de los manejes internos dentro del protocolo HTTP