Optimiza el tiempo hasta el primer byte

Descubre cómo optimizar la métrica Tiempo hasta el primer byte.

El tiempo hasta el primer byte (TTFB) es una métrica fundamental de rendimiento web que precede a todas las demás métricas significativas de la experiencia del usuario, como First Contentful Paint (FCP) y Largest Contentful Paint (LCP). Esto significa que los valores altos de TTFB agregan tiempo a las métricas que lo siguen.

Se recomienda que tu servidor responda a las solicitudes de navegación lo suficientemente rápido para que el percentil 75 de los usuarios experimente un FCP dentro del umbral “bueno”. Como guía general, la mayoría de los sitios deben esforzarse por tener un TTFB de 0.8 segundos o menos.

Los valores de TTFB buenos son de 0.8 segundos o menos, los valores deficientes son mayores que 1.8 segundos y cualquier otro valor debe mejorarse

Cómo medir el TTFB

Antes de poder optimizar el TTFB, debes observar cómo afecta a los usuarios de tu sitio web. Deberías basarte en los datos de campo como fuente principal para observar el TTFB como se ve afectado por los redireccionamientos, mientras que las herramientas basadas en labs a menudo se miden con la URL final, por lo que no tiene este retraso adicional.

PageSpeed Insights es una forma sencilla de obtener información de campo y lab para sitios web públicos que están disponibles en el Informe sobre la experiencia del usuario en Chrome.

El TTFB para usuarios reales se muestra en la sección superior Descubre lo que experimentan tus usuarios reales:

Datos de usuarios reales de PageSpeed Insights

En la auditoría del tiempo de respuesta del servidor, se muestra un subconjunto de TTFB:

Auditoría del tiempo de respuesta del servidor

Para descubrir más formas de medir el TTFB en el campo y en el lab, consulta la página de métricas de TTFB.

Comprensión del alto TTFB con Server-Timing

El encabezado de respuesta Server-Timing se puede usar en el backend de tu aplicación para medir los distintos procesos de backend que podrían contribuir a una latencia alta. La estructura del valor del encabezado es flexible y acepta, como mínimo, el controlador que definas. Los valores opcionales incluyen un valor de duración (mediante dur) y una descripción opcional legible por humanos (a través de desc).

Serving-Timing se puede usar para medir muchos procesos de backend de aplicaciones, pero hay algunos a los que te recomendamos prestar especial atención:

  • Consultas en base de datos
  • Tiempo de renderización del servidor, si corresponde
  • Búsquedas en el disco
  • Aciertos o errores de caché del servidor perimetral (si se usa una CDN)

Todas las partes de una entrada Server-Timing están separadas por dos puntos y varias entradas se pueden separar con comas:

// Two metrics with descriptions and values
Server-Timing: db;desc="Database";dur=121.3, ssr;desc="Server-side Rendering";dur=212.2

El encabezado se puede configurar con el lenguaje que prefieras del backend de tu aplicación. En PHP, por ejemplo, podrías configurar el encabezado de la siguiente manera:

<?php
// Get a high-resolution timestamp before
// the database query is performed:
$dbReadStartTime = hrtime(true);

// Perform a database query and get results...
// ...

// Get a high-resolution timestamp after
// the database query is performed:
$dbReadEndTime = hrtime(true);

// Get the total time, converting nanoseconds to
// milliseconds (or whatever granularity you need):
$dbReadTotalTime = ($dbReadEndTime - $dbReadStarTime) / 1e+6;

// Set the Server-Timing header:
header('Server-Timing: db;desc="Database";dur=' . $dbReadTotalTime);
?>

Cuando se establezca este encabezado, se mostrará información que puedes utilizar tanto en el lab como en el campo.

En el campo, cualquier página con un conjunto de encabezados de respuesta Server-Timing propagará la propiedad serverTiming en la API de Navigation Timing:

// Get the serverTiming entry for the first navigation request:
performance.getEntries("navigation")[0].serverTiming.forEach(entry => {
    // Log the server timing data:
    console.log(entry.name, entry.description, entry.duration);
});

En el lab, los datos del encabezado de respuesta Server-Timing se visualizarán en el panel de tiempos de la pestaña Red en las Herramientas para desarrolladores de Chrome:

Visualización de los valores de encabezado de Tiempo del servidor en la pestaña Red de las Herramientas para desarrolladores de Chrome. En esta imagen, los valores del encabezado de Tiempo del servidor miden si un servidor perimetral de CDN detectó un acierto o error de caché, así como el tiempo para recuperar el recurso de los servidores perimetrales y de origen.

Se visualizan los encabezados de respuesta Server-Timing en la pestaña Red de las Herramientas para desarrolladores de Chrome. Aquí, Server-Timing se usa para medir si la solicitud de un recurso llegó a la caché de la CDN, y cuánto tiempo tarda la solicitud en llegar al servidor perimetral de la CDN y, luego, al origen.

Una vez que hayas determinado que tienes un TTFB problemático mediante el análisis de los datos disponibles, puedes continuar con la solución del problema.

Formas de optimizar el TTFB

El aspecto más desafiante de la optimización del TTFB es que, si bien la pila de frontend de la Web siempre será HTML, CSS y JavaScript, las pilas de backend pueden variar de forma significativa. Existen numerosas pilas de backend y productos de bases de datos, cada uno con sus propias técnicas de optimización. Por lo tanto, esta guía se centrará en lo que se aplica a la mayoría de las arquitecturas, en lugar de enfocarse únicamente en la orientación específica de pilas.

Orientación específica de la plataforma

La plataforma que utilizas para tu sitio web puede tener un gran impacto en TTFB. Por ejemplo, el rendimiento de WordPress se ve afectado por la cantidad y la calidad de los complementos o por los temas que se utilizan. Otras plataformas se ven afectadas de manera similar cuando la plataforma se personaliza. Debes consultar la documentación de tu plataforma para obtener consejos específicos de proveedores y complementar los consejos de rendimiento más generales que se incluyen en esta publicación. La auditoría de Lighthouse para reducir los tiempos de respuesta del servidor también incluye una guía limitada específica de pilas.

Hosting, hosting, hosting

Antes de considerar otros enfoques de optimización, lo primero que debes tener en cuenta es el hosting. Aquí no se ofrece mucha orientación específica, pero una regla general es asegurarse de que el host de tu sitio web sea capaz de administrar el tráfico que le envías.

El hosting compartido suele ser más lento. Si estás ejecutando un pequeño sitio web personal que entrega principalmente archivos estáticos, es probable que esto sea correcto, y algunas de las técnicas de optimización que siguen te ayudarán a reducir ese TTFB tanto como sea posible.

Sin embargo, si estás ejecutando una aplicación más grande con muchos usuarios que implica personalización, consultas en bases de datos y otras operaciones intensivas del servidor, la elección del hosting se vuelve fundamental para reducir el TTFB en el campo.

A la hora de elegir un proveedor de hosting, ten en cuenta los siguientes aspectos:

  • ¿Cuánta memoria se asigna a la instancia de tu aplicación? Si tu aplicación no tiene memoria suficiente, se hiperpaginará y tendrá dificultades para entregar páginas lo más rápido posible.
  • ¿Tu proveedor de hosting mantiene actualizada tu pila de backend? A medida que se lanzan nuevas versiones de lenguajes de backend de la aplicación, implementaciones HTTP y software de base de datos, el rendimiento de ese software mejorará con el tiempo. Es clave asociarse con un proveedor de hosting que priorice este tipo de mantenimiento crucial.
  • Si tienes requisitos de aplicación muy específicos y quieres el acceso de menor nivel a los archivos de configuración del servidor, pregunta si tiene sentido personalizar el backend de tu propia instancia de aplicación.

Hay muchos proveedores de hosting que se encargarán de esto por ti, pero si comienzas a observar valores largos de TTFB, incluso en proveedores de hosting dedicado, puede ser una señal de que necesitas volver a evaluar las capacidades de tu proveedor de hosting actual para poder ofrecer la mejor experiencia del usuario posible.

Usar una red de distribución de contenidos (CDN)

El tema Uso de la CDN es sencillo, pero por un buen motivo: podrías tener un backend de aplicación muy bien optimizado, pero es posible que los usuarios que se encuentran lejos del servidor de origen aún experimenten un alto TTFB en el campo.

Las CDN resuelven el problema de la proximidad del usuario desde el servidor de origen mediante una red distribuida de servidores que almacenan en caché los recursos de los servidores que están físicamente más cerca de los usuarios. Estos servidores se denominan servidores perimetrales.

Los proveedores de CDN también pueden ofrecer beneficios más allá de los servidores perimetrales:

  • Los proveedores de CDN suelen ofrecer tiempos de resolución de DNS muy rápidos.
  • Es probable que una CDN entregue tu contenido desde servidores perimetrales mediante protocolos modernos como HTTP/2 o HTTP/3.
  • En particular, HTTP/3 resuelve el problema de bloqueo de cabeza de línea presente en TCP (en el que se basa HTTP/2) mediante el protocolo UDP.
  • Es probable que una CDN también proporcione versiones modernas de TLS, lo que disminuye la latencia involucrada en el tiempo de negociación de TLS. En particular, TLS 1.3 está diseñado para que la negociación de TLS sea lo más breve posible.
  • Algunos proveedores de CDN proporcionan una función que a menudo se conoce como "trabajador perimetral", que usa una API similar a la de la API de Service Worker para interceptar solicitudes, administrar de manera programática respuestas en cachés perimetrales o reescribir respuestas por completo.
  • Los proveedores de CDN son muy buenos para optimizar la compresión. La compresión es un proceso difícil de realizar por tu cuenta y, en algunos casos, puede generar tiempos de respuesta más lentos con lenguaje de marcado generado de forma dinámica, que debe comprimirse sobre la marcha.
  • Los proveedores de CDN también almacenan en caché automáticamente las respuestas comprimidas para los recursos estáticos, lo que genera la mejor combinación de índice de compresión y tiempo de respuesta.

Si bien adoptar una CDN implica un esfuerzo variado, desde trivial hasta significativo, debería ser una prioridad alta a la hora de optimizar tu TTFB si tu sitio web todavía no la utiliza.

Usaste contenido almacenado en caché siempre que fuera posible

Las CDN permiten que el contenido se almacene en caché en servidores perimetrales que se encuentran físicamente más cerca de los visitantes, siempre que el contenido esté configurado con los encabezados HTTP Cache-Control adecuados. Si bien esto no es apropiado para el contenido personalizado, solicitar un viaje hasta el origen puede anular gran parte del valor de una CDN.

En el caso de los sitios que actualizan su contenido con frecuencia, incluso un tiempo breve de almacenamiento en caché puede mejorar notablemente el rendimiento de los sitios ocupados, ya que solo el primer visitante durante ese tiempo experimenta por completo la latencia en el servidor de origen, mientras que todos los demás visitantes pueden reutilizar el recurso almacenado en caché del servidor perimetral. Algunas CDN permiten la invalidación de la caché en las versiones de sitios, lo que permite lo mejor de ambos mundos: tiempos de caché prolongados, pero actualizaciones instantáneas cuando es necesario.

Incluso cuando el almacenamiento en caché se configura correctamente, esto se puede ignorar mediante el uso de parámetros de cadena de consulta únicos para la medición de estadísticas. Estos pueden parecer contenidos diferentes en la CDN a pesar de ser iguales, por lo que no se usará la versión almacenada en caché.

Es posible que el contenido más antiguo o menos visitado tampoco se almacene en caché, lo que puede generar valores de TTFB más altos en algunas páginas que en otras. El aumento de los tiempos de almacenamiento en caché puede reducir el impacto de esto, pero ten en cuenta que con estos tiempos aumenta la posibilidad de entregar contenido potencialmente inactivo.

El impacto del contenido almacenado en caché no solo afecta a quienes usan CDN. Es posible que la infraestructura del servidor deba generar contenido a partir de costosas búsquedas en bases de datos cuando no se puede volver a usar el contenido almacenado en caché. Los datos a los que se accede con más frecuencia o las páginas almacenadas previamente en caché suelen tener un mejor rendimiento.

Evita que haya varias redirecciones de página

Un factor común de los resultados de un TTFB alto son los redireccionamientos. Los redireccionamientos ocurren cuando una solicitud de navegación de un documento recibe una respuesta que informa al navegador que el recurso existe en otra ubicación. Un redireccionamiento puede agregar latencia no deseada a una solicitud de navegación, pero puede empeorar si ese redireccionamiento apunta a otro recurso que genera otro redireccionamiento, y así sucesivamente. Esto puede afectar particularmente a los sitios que reciben grandes volúmenes de visitantes a partir de anuncios o boletines informativos, ya que a menudo redireccionan a través de servicios de análisis con fines de medición. Eliminar los redireccionamientos bajo tu control directo puede ayudar a lograr un buen TTFB.

Existen dos tipos de redireccionamientos:

  • Redireccionamientos del mismo origen, en los que el redireccionamiento ocurre completamente en tu sitio web
  • Redireccionamientos de origen cruzado en los que el redireccionamiento ocurre inicialmente en otro origen (por ejemplo, desde un servicio de acortamiento de URLs de redes sociales) antes de llegar a tu sitio web.

Enfócate en eliminar los redireccionamientos de mismo origen, ya que tendrás control directo sobre este método. Esto implica verificar los vínculos de tu sitio web para ver si alguno de ellos genera un código de respuesta 302 o 301. A menudo, esto puede ser el resultado de no incluir el esquema https:// (por lo que los navegadores usan http:// de forma predeterminada, que luego redirecciona) o porque las barras finales no se incluyen ni excluyen correctamente en la URL.

Los redireccionamientos de origen cruzado son más complicados, ya que suelen estar fuera de tu control. Sin embargo, evita los redireccionamientos múltiples siempre que sea posible, por ejemplo, usa varios acortadores de vínculos cuando los compartas. Asegúrese de que la URL proporcionada a los anunciantes o a los boletines informativos sea la URL final correcta para no agregar otro redireccionamiento a las que utilizan esos servicios.

Otra fuente importante de tiempo de redireccionamiento puede provenir de los redireccionamientos de HTTP a HTTPS. Una forma de evitar esto es usar el encabezado Strict-Transport-Security (HSTS), que aplicará HTTPS en la primera visita al origen y, luego, le indicará al navegador que acceda de inmediato al origen a través del esquema HTTPS en visitas futuras.

Una vez que hayas implementado una buena política de HSTS, podrás acelerar el proceso en la primera visita a un origen. Para ello, agrega tu sitio a la lista de precarga de HSTS.

Transmitir lenguaje de marcado al navegador

Los navegadores están optimizados para procesar el lenguaje de marcado de manera eficiente cuando se transmite, lo que significa que el lenguaje de marcado se maneja en fragmentos a medida que llega desde el servidor. Esto es crucial en lo que respecta a las cargas útiles de lenguaje de marcado de gran tamaño, ya que significa que el navegador puede analizar los fragmentos de lenguaje de marcado de forma incremental, en lugar de esperar a que llegue la respuesta completa antes de que pueda comenzar el análisis.

Si bien los navegadores son excelentes para manejar el lenguaje de marcado de transmisiones, es fundamental hacer todo lo posible para que la transmisión fluya, de modo que esos primeros fragmentos de lenguaje de marcado estén en camino lo antes posible. Si el backend retiene las cosas, hay un problema. Debido a que las pilas de backend son numerosas, cubrir cada pila y los problemas que podrían surgir en cada una de ellas estaría fuera del alcance de esta guía.

Por ejemplo, React, y otros frameworks que pueden renderizar lenguaje de marcado a pedido en el servidor, usaron un enfoque síncrono para la renderización del servidor. Sin embargo, las versiones más recientes de React implementaron métodos de servidor para el lenguaje de marcado de transmisiones a medida que se renderiza. Esto significa que no tienes que esperar a que un método de la API del servidor de React renderice toda la respuesta antes de que se envíe.

Otra forma de garantizar que el lenguaje de marcado se transmita rápidamente al navegador es usar el procesamiento estático, que genera archivos HTML durante el tiempo de compilación. Con el archivo completo disponible de inmediato, los servidores web pueden comenzar a enviar el archivo al instante, y la naturaleza inherente de HTTP dará como resultado lenguaje de marcado de transmisión. Si bien este enfoque no es adecuado para todas las páginas de todos los sitios web (como las que requieren una respuesta dinámica como parte de la experiencia del usuario), puede ser beneficioso para las páginas que no requieren lenguaje de marcado que se personalicen para un usuario específico.

Usa un service worker

La API de Service Worker puede tener un gran impacto en el TTFB de los documentos y de los recursos que cargan. Esto se debe a que un service worker actúa como un proxy entre el navegador y el servidor, pero el impacto en el TTFB de tu sitio web depende de cómo configures tu service worker y de si esa configuración se ajusta a los requisitos de tu aplicación.

  • Utiliza una estrategia de revalidación activa para los activos. Si un recurso se encuentra en la caché del service worker, ya sea un documento o un recurso que requiere el documento, la estrategia para el estado "stale-while-revalidar" ejecutará ese recurso primero desde la caché y, luego, lo descargará en segundo plano y lo entregará desde la caché para futuras interacciones.
    • Si tienes recursos de documentos que no cambian con mucha frecuencia, utilizar una estrategia de revalidación activa puede hacer que el TTFB de una página sea casi instantáneo. Sin embargo, esto no funciona muy bien si tu sitio web envía lenguaje de marcado generado de forma dinámica, como el lenguaje de marcado que cambia en función de si el usuario está autenticado. En esos casos, siempre te recomendamos que accedas a la red primero para que el documento esté lo más actualizado posible.
    • Si tu documento carga recursos no críticos que cambian con cierta frecuencia, pero recuperar el recurso inactivo no afectará en gran medida la experiencia del usuario (como imágenes seleccionadas u otros recursos que no son críticos), el TTFB de esos recursos se puede reducir en gran medida mediante una estrategia de revalidación de estado inactivo.
  • Si es posible, usa una arquitectura de service worker de transmisión. Esta arquitectura de service worker usa un enfoque en el que partes de un recurso del documento se almacenan en la caché del service worker y se combinan con parciales de contenido durante la solicitud de navegación. El resultado de usar este patrón de service worker es que la navegación será bastante rápida, mientras que las cargas útiles HTML más pequeñas se descargan de la red. Si bien este patrón de service worker no funciona en todos los sitios web, los tiempos de TTFB para los recursos de documentos pueden ser prácticamente instantáneos en el caso de los sitios que pueden utilizarlo.
  • Usa el modelo de shell de app para las aplicaciones renderizadas por el cliente. Este modelo se adapta mejor a las SPA, en las que la "shell" de la página se puede entregar al instante desde la caché del service worker, y el contenido dinámico de la página se propaga y se renderiza más adelante en el ciclo de vida de la página.

Usa 103 Early Hints para los recursos críticos de renderización

Sin importar qué tan bien esté optimizado el backend de tu aplicación, podría haber una cantidad significativa de trabajo que el servidor deba realizar para preparar una respuesta, incluido el trabajo costoso (pero necesario) de la base de datos que retrasa la respuesta de navegación para que no llegue lo más rápido posible. El efecto potencial de esto es que algunos de los recursos posteriores de carácter crítico para la renderización podrían retrasarse, como las CSS o, en algunos casos, el lenguaje JavaScript que renderiza el lenguaje de marcado en el cliente.

El encabezado 103 Early Hints es un código de respuesta anticipada que el servidor puede enviar al navegador mientras el backend está ocupado preparando el lenguaje de marcado. Este encabezado se puede usar para indicarle al navegador que hay recursos críticos de renderización que la página debe comenzar a descargar mientras se prepara el lenguaje de marcado. En el caso de la compatibilidad con navegadores, el efecto puede ser una renderización más rápida de documentos (CSS) y una disponibilidad más rápida de la funcionalidad principal de la página (JavaScript).

Conclusión

Debido a que hay muchas combinaciones de pilas de aplicaciones de backend, no existe un artículo que pueda encapsular todo lo que puedes hacer para reducir el TTFB de tu sitio web. Sin embargo, puedes explorar estas opciones para que todo funcione un poco más rápido en el servidor.

Al igual que con la optimización de todas las métricas, el enfoque es muy similar: mide tu TTFB en el campo, usa herramientas de lab para desglosar las causas y, luego, aplica optimizaciones cuando sea posible. No todas las técnicas que se usan aquí son viables para tu situación, pero algunas lo son. Como siempre, deberás vigilar de cerca los datos de campo y realizar los ajustes necesarios para garantizar la experiencia del usuario más rápida posible.

Hero image de Taylor Vick, obtenida de Unsplash.