TTFB - Reduciendo los tiempos de respuesta del servidor

Por Ricardo Cruz, 28 de Enero de 2019. Publicado en Rendimiento. 14 minutos de lectura.

¿Cómo mejorar la métrica Time To First Byte?, ¿es realmente importante?, ¿cómo afecta al SEO?. En este artículo te explico todo lo que necesitas saber y los consejos para que tu web sea todavía más rápida.

En la jerga de rendimiento, TTFB es el tiempo que tarda un servidor web en servir el primer byte de su respuesta.

TTFB

En algunos círculos se asocia reducir este tiempo a una mejora significativa en el posicionamiento web. Esto es una verdad a medias, que hay que coger con pinzas.

¿Cómo de importante es el TTFB y cómo afecta al posicionamiento de tu web?

Tal y como te contaba en el artículo “Herramientas para medir y mejorar la velocidad de tu web”, los buscadores viven de su credibilidad, y tratan de mostrarte primero los mejores resultados.

Los algoritmos de posicionamiento de Google, por ejemplo, siempre tratarán de mostrarte en los mejores puestos a las páginas más útiles, ligeras y rápidas, y no importa que leas esta frase hoy, o dentro de 10 años.

Por dejarlo claro, si aumentamos (empeoramos) en 5ms el TTFB por comprimir la respuesta en GZip, pero a cambio reducimos el tiempo total de descarga en 1 segundo, los buscadores te lo van a agradecer.

TTFB no es más que un síntoma de lo bien o mal que está optimizada tu página web, a nivel de servidor, ni más, ni menos.

Dicho esto, evidentemente te interesa tener un tiempo de espera al primer byte muy bajo. Pero no a base de engañar a los buscadores, reduciendo el TTFB y aumentando el tiempo de descarga del contenido, sino detectando cuáles son los cuellos de botella dentro de tu aplicación, y eliminándolos.

Y aquí no existen fórmulas mágicas, tendrás que trabajar esas optimizaciones.

¿Cómo reducir el “Time To First Byte” usando la caché del navegador?

Lo primero que deberías tratar de hacer es eliminar por completo la petición a tu sitio web, aprovechando la memoria caché del navegador del usuario.

Si navegas por esta web, por ejemplo, podrás notar que las páginas que ya has visitado se muestran de manera instantánea, si las vuelves a visitar, porque las guardo temporalmente en tu navegador. Lo mismo ocurre con los ficheros CSS, tipografías y JavaScript que se comparten en todas estas páginas.

Además, si puedo ahorrarle a tu navegador una petición a mi servidor, nos beneficiaremos ambos. Tú percibes un tiempo de carga más rápido, y yo no consumo recursos innecesarios (CPU y MB de transferencia) enviándote una y otra vez lo mismo.

Para hacerlo, hay tres cabeceras involucradas:

  • Expires: Al igual que un yogur, esta cabecera le muestra una fecha de expiración al navegador. Hasta que no llegue dicha fecha, el navegador podrá “consumir” la copia del recurso que tenga en su memoria caché, en lugar de hacer cada vez una nueva petición al servidor.

  • Cache-Control: Es similar y se puede combinar con la cabecera Expires. Sin embargo, Cache-Control te ofrece un control más exacto sobre el comportamiento de la caché del navegador, o de las cachés intermedias entre tu servidor y el usuario final, como por ejemplo un proxy.

  • ETag: Es un identificador único de una versión concreta de un recurso. También es compatible con Expires y Cache-Control. Se utiliza para que el servidor devuelva una versión más reciente de la petición, únicamente si se ha modificado. En caso de que el recurso siga siendo el mismo, el servidor podrá devolver simplemente un código “304 - Not Modified”, en lugar de todo el contenido.

Cualquiera de estas cabeceras de respuesta te valen para mejorar la velocidad de carga en peticiones recurrentes, sin embargo, combinándolas es como mayor partido conseguirás sacar.

La cabecera “Expires” tenderá a ir desapareciendo con el tiempo, a medida que las nuevas versiones de navegadores incorporen “Cache-Control” a su listado de características y, especialmente, cuando los usuarios dejen de utilizar sistemas operativos y navegadores que no se actualizarán más, como Internet Explorer.

Si utilizas las dos, los navegadores que soporten Cache-Control, le harán caso a esta cabecera.

Debes tener muchísimo cuidado al utilizar la caché del navegador, ya que no tendrás el control para hacer que expire si lo necesitas. Existen varias estrategias para resolver este problema, por ejemplo, renombrar el fichero cada vez que lo modifiques, o añadirle un “query string” al final con la fecha de la última modificación:

  • fichero.v3.js
  • fichero.js?ultima-edicion=2019-01-28

Busca una estrategia adecuada para tu caso particular. ¡Imaginación al poder!

En cuanto a ETag, existe un mito que dice que si lo desactivas, mejoras la velocidad de carga. Esto es simplemente una mala interpretación de algunos artículos anticuados, en los que explican que una mala configuración en determinados casos muy concretos, podría hacer que la cabecera perdiese efectividad.

En estos artículos, sugieren que nunca envíes la cabecera ETag para ahorrar el envío de alrededor de 20 bytes. Para que compares, Google Analytics envía un fichero JavaScript que ocupa 17404 bytes (~17KB).

Mejorando el TTFB usando la caché del servidor

No siempre podemos utilizar la caché del navegador. En muchas ocasiones, tenemos que generar incluso una página cada vez que un usuario nos visita.

El tiempo que tarda nuestro servidor en generar esta respuesta y empezar a enviarla, es precisamente el Time To First Byte. Un TTFB alto puede ser síntoma de una pieza de código que no está bien optimizada.

Hay principalmente tres tipos de problemas en este sentido:

1. Un bloque de código lento que se ejecuta una o pocas veces

Esto podría ser una consulta a la base de datos muy pesada, por ejemplo, pedirle a la base de datos todos los comentarios que hay en el blog, para luego filtrarlos en el código excluyendo los que no pertenezcan a ese artículo.

Podría ser también una consulta a un proveedor externo para que nos envíe la predicción del tiempo y mostrarla en nuestra página.

Un último ejemplo sería un cálculo intensivo, como calcular el primer millón de dígitos del número Pi.

2. Un bloque de código muy rápido que se ejecuta demasiadas veces

Una consulta a la base de datos que sea muy eficiente, pero que se haga mil veces, podría ser un problema de rendimiento, al igual que leer una y otra vez un fichero de configuración.

Incluso cuando no hay lecturas de la base de datos o en el sistema de ficheros, una operación que se ejecuta demasiadas veces, siempre será un problema si se le añaden la cantidad de peticiones adecuadas.

Es muy llamativo, además, cuando estas operaciones a su vez generan miles de llamadas innecesarias a otras piezas de código.

3. Un bloque de código lento que se ejecuta muchas veces

Este es el peor caso de todos. Una consulta lenta a la base de datos en un bucle.

Imagínate tener que generar la página del perfil de usuario de un foro, en la que cada vez recorriésemos cada uno de los mensajes que ha enviado simplemente para mostrar un contador.

La manera de corregir estos tres problemas, pasa por la caché. Y puede ser tan sencillo como escribir el resultado de la operación en una variable, un fichero, o un repositorio en memoria especializado, como Redis y Memcached.

Por ejemplo, ese primer millón de dígitos de Pi, aunque cueste mucho generarlos, nos servirán para siempre. Podríamos guardarlos en un fichero y consultarlo cuando fuera necesario, en lugar de generarlos en cada petición.

Al igual que con la caché del navegador, también hay que elegir una buena estrategia para purgar la caché siempre que lo necesitemos.

Hay que tener mucho ojo a la hora de detectar estos errores, ya que nos podemos llevar por instinto. En este caso, siempre tendremos que fiarnos de herramientas que nos digan exactamente dónde está el problema. Aunque puedas optar por trazas de “profiling”, usando Valgrind o similar, yo te recomiendo usar un “Application Performance Monitoring” (APM). New Relic es simplemente genial.

Por último, introducir Varnish a la ecuación, puede darte muy buenos resultados. Échale un ojo al artículo “Catapulta la velocidad de tu sitio web con Varnish”, en este mismo blog, para más información.

Plugins, extensiones y módulos

Si en tu caso utilizas un gestor de contenidos tipo Wordpress, Drupal, Ghost y similares, siempre puedes optar por instalar un plugin para optimizar la carga de tu página.

WP Super Cache, por ejemplo, se encarga de resolver, de manera automática, muchos de los problemas de rendimiento que arrastra Wordpress.

En cuanto a Drupal, hay incluso módulos que se integran con Varnish.

Como consejo general, trata de buscar siempre extensiones oficiales y con buenas valoraciones.

Generadores de Sitios Web Estáticos

Si quieres que tu sitio web vaya a la máxima velocidad posible, puedes optar por un generador de sitios web estáticos, como Hugo, Jekyll, Gatsby o Grow.

Todos estas herramientas funcionan de manera similar, convierten tus documentos en páginas web estáticas, HTML puro y duro, que tu servidor puede servir como si de un fichero de texto se tratase.

No te dejes engañar. Con estos generadores se pueden crear auténticas obras de arte llenas de dinamismo, gracias a la potencia de CSS y la ayuda de JavaScript.

Independientemente del que utilices, la velocidad de carga en el navegador siempre será la misma, ya que el fichero final será un HTML estático. En sitios gigantes, con miles de páginas, sí que tendrás que probar y elegir bien el que más te interese. Para que te hagas una idea, todo este sitio web se genera con Jekyll en apenas medio segundo.

¿Necesitas una guía para empezar?, te dejo con la introducción para crear sitios web con Jekyll que publiqué hace unas semanas.

Conclusión

Como has podido comprobar, reducir el tiempo que tarda tu servidor en generar una respuesta, no es cuestión de apretar el botón de volar del coche fantástico. También hemos desmentido algunos mitos y leyendas que giran en torno al TTFB y a los ETag.

Para que cualquier pieza de software sea rápida, es fundamental reducir las llamadas a bases de datos y al disco duro, utilizar una caché siempre que sea posible y tratar de evitar, en primer lugar, tener que procesar un bloque de código, por ejemplo, usando sitios web estáticos.

Poco más que añadir, de lectura adicional, te recomiendo esta guía completísima sobre caché:

¡Hasta el próximo artículo!

Sigue leyendo