Cargas más rápidas de páginas utilizando el tiempo de reflexión del servidor con Sugerencias iniciales.

Descubre cómo tu servidor puede enviar sugerencias al navegador sobre subrecursos fundamentales.

Kenji Baheux
Kenji Baheux

¿Qué es Early Hints?

Los sitios web se han vuelto más sofisticados con el tiempo. Por lo tanto, no es inusual que un servidor necesite realizar un trabajo no trivial (por ejemplo, acceso a bases de datos o CDN que acceden al servidor de origen) para producir el HTML para la página solicitada. Lamentablemente, este "tiempo de reflexión del servidor" genera latencia adicional antes de que el navegador pueda comenzar a procesar la página. De hecho, la conexión queda inactiva durante el tiempo que el servidor tarde en preparar la respuesta.

Imagen en la que se muestra el lapso de tiempo de 200 ms entre la carga de la página y la carga de otros recursos del servidor.
Sin las sugerencias tempranas: Todo está bloqueado en el servidor y determina cómo responder al recurso principal.

Early Hints es un código de estado HTTP (103 Early Hints) que se usa para enviar una respuesta HTTP preliminar antes de una respuesta final. Esto permite que un servidor envíe sugerencias al navegador sobre subrecursos críticos (por ejemplo, una hoja de estilo para la página o JavaScript crítico), o bien acerca de los orígenes que probablemente utilizará la página, mientras el servidor está ocupado generando el recurso principal. El navegador puede usar esas sugerencias para preparar las conexiones y solicitar subrecursos mientras espera el recurso principal. En otras palabras, Early Hints ayuda al navegador a aprovechar este "tiempo de reflexión del servidor" al realizar algunas tareas con anticipación, lo que acelera la carga de páginas.

Imagen en la que se muestra cómo Early Hints permite que la página envíe una respuesta parcial.
Con las sugerencias tempranas: El servidor puede entregar una respuesta parcial con sugerencias de recursos mientras determina la respuesta final.

En algunos casos, la mejora del rendimiento del Largest Contentful Paint puede ser de varios cientos de milisegundos, como observan Shopify y Cloudflare, y hasta un segundo más rápido, como se observa en la comparación anterior y posterior:

Comparación de dos sitios
Comparación previa y posterior de las sugerencias tempranas en un sitio web de prueba realizada con WebPageTest (Moto G4 - DSL)

Cómo implementar las sugerencias anticipadas

Antes de profundizar en el tema, ten en cuenta que las Early Hints no son útiles si tu servidor puede enviar un 200 (u otras respuestas finales) de inmediato. En su lugar, considera usar el link rel=preload o el link rel=preconnect normales en la respuesta principal (encabezado HTTP rel. HTTP) o en la respuesta principal (elementos <link>), en esas situaciones. En los casos en los que tu servidor necesite un poco de tiempo para generar la respuesta principal, sigue leyendo.

El primer paso para aprovechar las sugerencias tempranas consiste en identificar las páginas de destino principales, es decir, las páginas en las que los usuarios suelen comenzar cuando visitan tu sitio web. Puede ser la página principal o las páginas populares de fichas de productos si tienes muchos usuarios que provienen de otros sitios web. La razón por la que estos puntos de entrada son más importantes que otras páginas es porque la utilidad de Early Hints disminuye a medida que el usuario navega por tu sitio web (es decir, es más probable que el navegador tenga todos los subrecursos que necesita en la segunda o tercera navegación posterior). Además, siempre es buena idea entregar una primera impresión excelente.

Ahora que tienes esta lista priorizada de páginas de destino, el siguiente paso consiste en identificar qué orígenes o subrecursos serían buenos candidatos para sugerencias de preconexión o precarga, como primera aproximación. Por lo general, se trata de orígenes y subrecursos que más contribuyen a las métricas clave del usuario, como Largest Contentful Paint o First Contentful Paint. De manera más concreta, busca subrecursos que bloqueen el procesamiento, como JavaScript síncrono, hojas de estilo o incluso fuentes web. Del mismo modo, busca orígenes que alojen subrecursos que contribuyan en gran medida a las métricas clave del usuario. Nota: Si tus recursos principales ya usan <link rel=preconnect> o <link rel=preload>, puedes considerarlos entre los candidatos para las sugerencias tempranas. Consulta este artículo para obtener más detalles.

El segundo paso consiste en minimizar el riesgo de usar las sugerencias tempranas en orígenes o recursos que podrían quedar obsoletos o que el recurso principal ya no use. Por ejemplo, es posible que los recursos que se actualizan y se controlan versiones con frecuencia (por ejemplo, example.com/css/main.fa231e9c.css) no sean la mejor opción. Ten en cuenta que esta preocupación no es específica de las sugerencias anticipadas, sino que se aplica a cualquier vínculo rel=preload o rel=preconnect, independientemente de dónde se encuentren. Este es el tipo de detalle que se aborda mejor con la automatización o las plantillas (por ejemplo, es más probable que un proceso manual genere discrepancias en el hash o las URLs de versión entre link rel=preload y la etiqueta HTML real que usa el recurso).

Como ejemplo, considera el siguiente flujo:

GET /main.html
Host: example.com
User-Agent: [....] Chrome/103.0.0.0 [...]

El servidor predice que se necesitará main.abcd100.css y sugiere precargarlo mediante Early Hints:

103 Early Hints
Link: </main.abcd100.css>; rel=preload; as=style
[...]

Unos segundos más tarde, se publica la página web, incluido el CSS vinculado. Lamentablemente, este recurso de CSS se actualiza con frecuencia y el recurso principal ya tiene cinco versiones anteriores (abcd105) del recurso de CSS previsto (abcd100).

200 OK
[...]
<HTML>
<head>
   <title>Example</title>
   <link rel="stylesheet" href="/main.abcd105.css">

En general, busca recursos y orígenes que sean bastante estables y, en gran medida, independientes del resultado del recurso principal. Si es necesario, considera dividir tus recursos clave en dos: una parte estable diseñada para usarse con Early Hints y una parte más dinámica que se debe recuperar después de que el navegador recibe el recurso principal:

<HTML>
<head>
   <title>Example</title>
   <link rel="stylesheet" href="/main.css">
   <link rel="stylesheet" href="/experimental.3eab3290.css">

Por último, en el servidor, busca solicitudes de recursos principales enviadas por navegadores conocidos por admitir Early Hints y responde de inmediato con 103 Early Hints. En la respuesta 103, incluye las sugerencias relevantes de preconexión y precarga. Una vez que el recurso principal esté listo, continúa con la respuesta habitual (por ejemplo, 200 OK si se completó correctamente). Para retrocompatibilidad, se recomienda incluir también encabezados HTTP Link en la respuesta final, tal vez incluso aumentar con recursos críticos que se volvieron evidentes como parte de la generación del recurso principal (por ejemplo, la parte dinámica de un recurso de clave si seguiste la sugerencia "dividir en dos"). Así es como se vería:

GET /main.html
Host: example.com
User-Agent: [....] Chrome/103.0.0.0 [...]
103 Early Hints
Link: <https://fonts.google.com>; rel=preconnect
Link: </main.css>; rel=preload; as=style
Link: </common.js>; rel=preload; as=script

Después de un momento:

200 OK
Content-Length: 7531
Content-Type: text/html; charset=UTF-8
Content-encoding: br
Link: <https://fonts.google.com>; rel=preconnect
Link: </main.css>; rel=preload; as=style
Link: </common.js>; rel=preload; as=script
Link: </experimental.3eab3290.css>; rel=preload; as=style
<HTML>
<head>
   <title>Example</title>
   <link rel="stylesheet" href="/main.css">
   <link rel="stylesheet" href="/experimental.3eab3290.css">
   <script src="/common.js"></script>
   <link rel="preconnect" href="https://fonts.googleapis.com">

Navegadores compatibles

Aunque 103 Early Hints es compatible con todos los navegadores principales, las directivas que se pueden enviar en Early Hint difieren según el navegador:

Compatibilidad con la preconexión:

Navegadores compatibles

  • 103
  • 103
  • 120
  • 17

Compatibilidad con la precarga:

Navegadores compatibles

  • 103
  • 103
  • x

Asistencia para servidores

A continuación, se incluye un breve resumen del nivel de compatibilidad con Early Hints entre el software popular del servidor HTTP OSS:

Habilitar Early Hints, la manera sencilla

Si usas una de las siguientes CDN o plataformas, es posible que no necesites implementar Early Hints de forma manual. Consulta la documentación en línea de tu proveedor de soluciones para averiguar si admite las Early Hints, o consulta la lista no exhaustiva aquí:

Evita problemas para clientes que no admiten Early Hints

Las respuestas HTTP informativas en el rango 100 forman parte del estándar HTTP, pero algunos clientes o bots más antiguos pueden tener dificultades con esto porque, antes del lanzamiento de 103 Early Hints, rara vez se utilizaban para la navegación web general.

La emisión solo de 103 Early Hints en respuesta a los clientes que envían un encabezado de solicitud HTTP sec-fetch-mode: navigate debe garantizar que estas sugerencias solo se envíen para clientes más nuevos que sepan esperar la respuesta posterior. Además, dado que las sugerencias anticipadas solo se admiten en las solicitudes de navegación (consulta las limitaciones actuales), esto tiene el beneficio adicional de evitar el envío innecesario de estas solicitudes en otras solicitudes.

Además, se recomienda que las sugerencias anticipadas se envíen solo a través de conexiones HTTP/2 o HTTP/3.

Patrón avanzado

Si aplicaste por completo las sugerencias iniciales a tus páginas de destino clave y buscas más oportunidades, es posible que te interese el siguiente patrón avanzado.

En el caso de los visitantes que realizan la na solicitud de página como parte de un recorrido típico del usuario, recomendamos que adaptes la respuesta de Early Hints al contenido que se encuentra más abajo en la página, es decir, usando Early Hints en recursos de menor prioridad. Esto puede sonar contradictorio, dado que recomendamos que nos enfoquemos en orígenes o subrecursos que bloquean la renderización de alta prioridad. Sin embargo, para cuando un visitante haya navegado durante un tiempo, es muy probable que su navegador ya tenga todos los recursos críticos. A partir de ese momento, podría tener sentido dirigir tu atención a los recursos de menor prioridad. Por ejemplo, esto podría significar usar Early Hints para cargar imágenes de productos o JS/CSS adicional que solo se necesitan para interacciones menos comunes de los usuarios.

Limitaciones actuales

Estas son las limitaciones de las Sugerencias anticipadas implementadas en Chrome:

  • Solo está disponible para las solicitudes de navegación (es decir, el recurso principal del documento de nivel superior).
  • Solo admite preconnect y preload (es decir, prefetch no es compatible).
  • Una sugerencia anticipada seguida de un redireccionamiento de origen cruzado en la respuesta final hará que Chrome quite los recursos y las conexiones que obtuvo mediante las sugerencias anticipadas.

Otros navegadores tienen limitaciones similares y restringen aún más las sugerencias anticipadas 103 solo a preconnect.

¿Qué sigue?

Según el interés de la comunidad, es posible que aumentemos nuestra implementación de Early Hints con las siguientes capacidades:

  • Sugerencias anticipadas enviadas en solicitudes de subrecursos.
  • Se enviaron las sugerencias anticipadas en las solicitudes de recursos principales de iframe.
  • Compatibilidad con la carga previa en Early Hints.

Agradecemos que nos envíes tus comentarios sobre los aspectos que debes priorizar y sobre cómo mejorar aún más las sugerencias tempranas.

Relación con H2/Push

Si estás familiarizado con la función de HTTP2/Push obsoleta, es posible que te preguntes en qué se diferencian las Early Hints. Si bien Early Hints requiere un proceso de ida y vuelta para que el navegador comience a recuperar subrecursos críticos, con HTTP2/Push, el servidor podría empezar a enviar subrecursos junto con la respuesta. Si bien esto suena increíble, generó una desventaja estructural clave: con HTTP2/Push, era muy difícil evitar enviar subrecursos que el navegador ya tenía. Este efecto de “empuje excesivo” dio como resultado un uso menos eficiente del ancho de banda de red, lo que obstaculizó significativamente los beneficios de rendimiento. En general, los datos de Chrome mostraron que HTTP2/Push fue, de hecho, un aspecto negativo del rendimiento en toda la Web.

En cambio, Early Hints funciona mejor en la práctica, ya que combina la capacidad de enviar una respuesta preliminar con sugerencias que dejan al navegador a cargo de recuperar o conectarse con lo que realmente necesita. Si bien Early Hints no abarca todos los casos de uso que HTTP2/Push podrían abordar en teoría, creemos que Early Hints es una solución más práctica para acelerar las navegaciones.

Miniatura de Pierre Bamin.