Adapta la app a usuarios con Client Hints

Desarrollar sitios que sean rápidos en todas partes puede ser una tarea complicada. La gran cantidad de funciones de los dispositivos y la calidad de las redes a las que se conectan pueden hacer que parezca una tarea insuperable. Si bien podemos aprovechar las funciones del navegador para mejorar el rendimiento de carga, ¿cómo sabemos qué es capaz de hacer el dispositivo del usuario o la calidad de su conexión de red? La solución son los sugerencias para el cliente.

Las sugerencias del cliente son un conjunto de encabezados de solicitud HTTP con solicitud de aceptación que nos brindan información sobre estos aspectos del dispositivo del usuario y la red a la que está conectado. Si aprovechamos esta información del servidor, podemos cambiar cómo entregamos el contenido según las condiciones del dispositivo o de la red. Esto puede ayudarnos a crear experiencias del usuario más inclusivas.

Todo se trata de la negociación de contenido

Las sugerencias del cliente son otro método de negociación de contenido, lo que significa que se cambian las respuestas del contenido según los encabezados de solicitud del navegador.

Un ejemplo de negociación de contenido incluye el encabezado de solicitud Accept. Describe los tipos de contenido que comprende el navegador, que el servidor puede usar para negociar la respuesta. En el caso de las solicitudes de imágenes, el contenido del encabezado Accept de Chrome es el siguiente:

Accept: image/webp,image/apng,image/*,*/*;q=0.8

Si bien todos los navegadores admiten formatos de imagen como JPEG, PNG y GIF, en este caso, Accept indica que el navegador también admite WebP y APNG. Con esta información, podemos negociar los mejores tipos de imágenes para cada navegador:

<?php
// Check Accept for an "image/webp" substring.
$webp = stristr($_SERVER["HTTP_ACCEPT"], "image/webp") !== false ? true : false;

// Set the image URL based on the browser's WebP support status.
$imageFile = $webp ? "whats-up.webp" : "whats-up.jpg";
?>
<img src="<?php echo($imageFile); ?>" alt="I'm an image!">

Al igual que Accept, las sugerencias del cliente son otra forma de negociar contenido, pero en el contexto de las capacidades del dispositivo y las condiciones de la red. Con las sugerencias del cliente, podemos tomar decisiones de rendimiento del servidor en función de la experiencia individual de un usuario, como decidir si se deben entregar recursos no esenciales a los usuarios con condiciones de red deficientes. En esta guía, describiremos todas las sugerencias disponibles y algunas formas en que puedes usarlas para que la entrega de contenido sea más flexible para los usuarios.

Cómo habilitarlo

A diferencia del encabezado Accept, las sugerencias del cliente no aparecen de forma mágica (con la excepción de Save-Data, que analizaremos más adelante). Para mantener los encabezados de solicitud en un mínimo, deberás habilitar las sugerencias de cliente que deseas recibir enviando un encabezado Accept-CH cuando un usuario solicite un recurso:

Accept-CH: Viewport-Width, Downlink

El valor de Accept-CH es una lista de sugerencias solicitadas separadas por comas que el sitio usará para determinar los resultados de la solicitud de recursos posterior. Cuando el cliente lee este encabezado, se le dice que “este sitio quiere las sugerencias de cliente Viewport-Width y Downlink”. No te preocupes por las sugerencias específicas. Hablaremos de ellos en un momento.

Puedes configurar estos encabezados de habilitación en cualquier lenguaje de backend. Por ejemplo, se podría usar la función header de PHP. Incluso puedes configurar estos encabezados de habilitación con el atributo http-equiv en una etiqueta <meta>:

<meta http-equiv="Accept-CH" content="Viewport-Width, Downlink" />

Todas las sugerencias del cliente

Las sugerencias del cliente describen una de dos opciones: el dispositivo que usan tus usuarios y la red que usan para acceder a tu sitio. Veamos brevemente todos los sugerencias disponibles.

Sugerencias de dispositivos

Algunas sugerencias del cliente describen las características del dispositivo del usuario, por lo general, las características de la pantalla. Algunos de ellos pueden ayudarte a elegir el recurso multimedia óptimo para la pantalla de un usuario determinado, pero no todos se centran necesariamente en el contenido multimedia.

Antes de comenzar con esta lista, puede ser útil conocer algunos términos clave que se usan para describir las pantallas y la resolución de contenido multimedia:

Tamaño intrínseco: Son las dimensiones reales de un recurso multimedia. Por ejemplo, si abres una imagen en Photoshop, las dimensiones que se muestran en el diálogo de tamaño de la imagen describen su tamaño intrínseco.

Tamaño intrínseco corregido por densidad: Son las dimensiones de un recurso multimedia después de que se corrigió la densidad de píxeles. Es el tamaño intrínseco de la imagen dividido por una proporción de píxeles del dispositivo. Por ejemplo, tomemos este marcado:

<img
  src="whats-up-1x.png"
  srcset="whats-up-2x.png 2x, whats-up-1x.png 1x"
  alt="I'm that image you wanted."
/>

Supongamos que el tamaño intrínseco de la imagen 1x en este caso es de 320 x 240 y el tamaño intrínseco de la imagen 2x es de 640 x 480. Si un cliente instalado en un dispositivo con una relación de píxeles de pantalla de 2 (p.ej., una pantalla Retina) analiza este marcado, se solicita la imagen 2x. El tamaño intrínseco corregido por densidad de la imagen 2x es de 320 x 240, ya que 640 x 480 dividido por 2 es 320 x 240.

Tamaño extrínseco: es el tamaño de un recurso multimedia después de que se le aplicaron CSS y otros factores de diseño (como los atributos width y height). Supongamos que tienes un elemento <img> que carga una imagen con un tamaño intrínseco corregido por densidad de 320 × 240, pero también tiene propiedades width y height de CSS con valores de 256px y 192px aplicados, respectivamente. En este ejemplo, el tamaño extrínseco de ese elemento <img> se convierte en 256 × 192.

Ilustración del tamaño intrínseco en comparación con el tamaño extrínseco. Se muestra un cuadro de 320 × 240 píxeles con la etiqueta INTRINSIC
SIZE. Dentro de él, hay un cuadro más pequeño de 256 × 192 píxeles, que representa un elemento img HTML con CSS aplicado. Esta casilla está etiquetada como EXTRINSIC 
SIZE. A la derecha, hay un cuadro que contiene CSS aplicado al elemento que modifica el diseño del elemento img para que su tamaño extrínseco difiera de su tamaño intrínseco.
Figura 1. Ilustración del tamaño intrínseco en comparación con el tamaño extrínseco. Una imagen obtiene su tamaño extrínseco después de que se le aplican los factores de diseño. En este caso, aplicar las reglas de CSS de width: 256px; y height: 192px; transforma una imagen de tamaño intrínseco de 320 x 240 en una de tamaño extrínseco de 256 x 192.

Ahora que conoces la terminología, veamos la lista de sugerencias de cliente específicas para el dispositivo que tienes a tu disposición.

Viewport-Width

Viewport-Width es el ancho del viewport del usuario en píxeles de CSS:

Viewport-Width: 320

Esta sugerencia se puede usar con otras sugerencias específicas de la pantalla para entregar diferentes tratamientos (es decir, recortes) de una imagen que son óptimos para tamaños de pantalla específicos (es decir, dirección de arte) o para omitir recursos que no son necesarios para el ancho de pantalla actual.

DPR

DPR, que significa relación de píxeles del dispositivo, informa la proporción de píxeles físicos a píxeles de CSS de la pantalla del usuario:

DPR: 2

Esta sugerencia es útil cuando se seleccionan fuentes de imágenes que corresponden a la densidad de píxeles de una pantalla (como lo hacen los descriptores x en el atributo srcset).

Ancho

La sugerencia Width aparece en las solicitudes de recursos de imagen que activan las etiquetas <img> o <source> con el atributo sizes. sizes le indica al navegador cuál será el tamaño extrínseco del recurso. Width usa ese tamaño extrínseco para solicitar una imagen con un tamaño intrínseco que sea óptimo para el diseño actual.

Por ejemplo, supongamos que un usuario solicita una página con una pantalla de 320 píxeles de CSS de ancho con una DPR de 2. El dispositivo carga un documento con un elemento <img> que contiene un valor de atributo sizes de 85vw (es decir, 85% del ancho de la ventana de visualización para todos los tamaños de pantalla). Si se habilitó la sugerencia Width, el cliente enviará esta sugerencia Width al servidor con la solicitud de src de <img>:

Width: 544

En este caso, el cliente le insinúa al servidor que un ancho intrínseco óptimo para la imagen solicitada sería el 85% del ancho de la vista (272 píxeles) multiplicado por el DPR de la pantalla (2), que equivale a 544 píxeles.

Esta sugerencia es especialmente potente porque no solo tiene en cuenta el ancho corregido por densidad de la pantalla, sino que también concilia esta información fundamental con el tamaño extrínseco de la imagen dentro del diseño. Esto les brinda a los servidores la oportunidad de negociar respuestas de imágenes que sean óptimas para la pantalla y el diseño.

Content-DPR

Si bien ya sabes que las pantallas tienen una proporción de píxeles del dispositivo, los recursos también tienen sus propias proporciones de píxeles. En los casos de uso de selección de recursos más simples, las proporciones de píxeles entre dispositivos y recursos pueden ser las mismas. Pero En los casos en que los encabezados DPR y Width están en juego, el tamaño extrínseco de un recurso puede producir situaciones en las que ambos difieren. Aquí es donde entra en juego la sugerencia Content-DPR.

A diferencia de otras sugerencias del cliente, Content-DPR no es un encabezado de solicitud que los servidores deben usar, sino un encabezado de respuesta que los servidores deben enviar cada vez que se usan las sugerencias DPR y Width para seleccionar un recurso. El valor de Content-DPR debe ser el resultado de esta ecuación:

Content-DPR = [Tamaño del recurso de imagen seleccionada] / ([Width] / [DPR])

Cuando se envíe un encabezado de solicitud Content-DPR, el navegador sabrá cómo escalar la imagen determinada para la relación de píxeles del dispositivo de la pantalla y el diseño. Sin él, es posible que las imágenes no se ajusten correctamente.

Device-Memory

Técnicamente, es parte de la API de Device Memory. Device-Memory revela la cantidad aproximada de memoria que tiene el dispositivo actual en GiB:

Device-Memory: 2

Un posible caso de uso para esta sugerencia sería reducir la cantidad de JavaScript que se envía a los navegadores en dispositivos con memoria limitada, ya que JavaScript es el tipo de contenido que más recursos intensivos de los navegadores suelen cargar. También puedes enviar imágenes con una DPR más baja, ya que usan menos memoria para decodificarse.

Sugerencias de red

La API de Network Information proporciona otra categoría de sugerencias de cliente que describen el rendimiento de la conexión de red del usuario. En mi opinión, este es el conjunto de sugerencias más útil. Con ellos, podemos personalizar las experiencias para los usuarios cambiando la forma en que entregamos recursos a los clientes con conexiones lentas.

RTT

La sugerencia RTT proporciona el tiempo de ida y vuelta aproximado, en milisegundos, en la capa de aplicación. A diferencia de la RTT de la capa de transporte, la sugerencia RTT incluye el tiempo de procesamiento del servidor.

RTT: 125

Esta sugerencia es útil debido al rol que desempeña la latencia en el rendimiento de carga. Con la sugerencia RTT, podemos tomar decisiones en función de la capacidad de respuesta de la red, lo que puede ayudar a acelerar la entrega de una experiencia completa (p.ej., omitiendo algunas solicitudes).

Si bien la latencia es importante en el rendimiento de carga, el ancho de banda también es influyente. La sugerencia Downlink, expresada en megabits por segundo (Mbps), revela la velocidad de descarga aproximada de la conexión del usuario:

Downlink: 2.5

Junto con RTT, Downlink puede ser útil para cambiar la forma en que se entrega el contenido a los usuarios según la calidad de una conexión de red.

ECT

La sugerencia ECT significa Tipo de conexión real. Su valor es uno de una lista enumerada de tipos de conexión, cada uno de los cuales describe una conexión dentro de rangos especificados de valores de RTT y Downlink.

Este encabezado no explica cuál es el tipo de conexión real; por ejemplo, no informa si tu puerta de enlace es una torre celular o un punto de acceso Wi-Fi. En cambio, analiza la latencia y el ancho de banda de la conexión actual y determina a qué perfil de red se parece más. Por ejemplo, si te conectas a través de Wi-Fi a una red lenta, es posible que ECT se propague con un valor de 2g, que es la aproximación más cercana de la conexión efectiva:

ECT: 2g

Los valores válidos para ECT son 4g, 3g, 2g y slow-2g. Esta sugerencia se puede usar como punto de partida para evaluar la calidad de la conexión y, luego, definirla mejor con las sugerencias RTT y Downlink.

Save-Data

Save-Data no es tanto una sugerencia que describe las condiciones de la red, sino una preferencia del usuario que indica que las páginas deben enviar menos datos.

Prefiero clasificar Save-Data como una sugerencia de red porque muchas de las acciones que harías con ella son similares a otras sugerencias de red. Es probable que los usuarios también lo habiliten en entornos de alta latencia o bajo ancho de banda. Cuando está presente, esta sugerencia siempre se ve de la siguiente manera:

Save-Data: on

En Google, hemos hablado sobre lo que puedes hacer con Save-Data. El impacto que puede tener en el rendimiento puede ser profundo. Es una señal en la que los usuarios te piden que les envíes menos contenido. Si escuchas y actúas en función de esa señal, los usuarios lo apreciarán.

Cómo juntar las piezas

Depende de ti qué hacer con las sugerencias del cliente. Debido a que ofrecen mucha información, tienes muchas opciones. Para que fluyan las ideas, veamos lo que las sugerencias para el cliente pueden hacer por Sconnie Timber, una empresa ficticia de madera ubicada en el norte rural del Medio Oeste. Como suele suceder en las áreas remotas, las conexiones de red pueden ser frágiles. Aquí es donde una tecnología como las sugerencias para clientes puede marcar la diferencia para los usuarios.

Imágenes responsivas

Todos los casos de uso de imágenes responsivas, excepto los más simples, pueden complicarse. ¿Qué sucede si tienes varios tratamientos y variantes de las mismas imágenes para diferentes tamaños de pantalla y formatos? Ese marcado se vuelve muy complicado muy rápido. Es fácil cometer errores y olvidar o malinterpretar conceptos importantes (como sizes).

Si bien <picture> y srcset son herramientas fantásticas, pueden requerir mucho tiempo de desarrollo y mantenimiento para casos de uso complejos. Podemos automatizar la generación de marcado, pero hacerlo también es difícil porque la funcionalidad que proporcionan <picture> y srcset es lo suficientemente compleja como para que su automatización se realice de una manera que mantenga la flexibilidad que proporcionan.

Las sugerencias del cliente pueden simplificar esto. La negociación de respuestas de imágenes con sugerencias del cliente podría verse de la siguiente manera:

  1. Si corresponde a tu flujo de trabajo, primero selecciona un tratamiento de imagen (es decir, imágenes dirigidas por el equipo de arte) marcando la sugerencia Viewport-Width.
  2. Para seleccionar una resolución de imagen, marca la sugerencia Width y la sugerencia DPR, y elige una fuente que se ajuste al tamaño del diseño y la densidad de la pantalla de la imagen (similar a cómo funcionan los descriptores x y w en srcset).
  3. Selecciona el formato de archivo más óptimo que admita el navegador (algo que Accept nos ayuda a hacer en la mayoría de los navegadores).

En el caso de mi cliente ficticio de la empresa maderera, desarrollé una rutina de selección de imágenes responsivas ingenua en PHP que usa sugerencias del cliente. Esto significaba que, en lugar de enviar este marcado a todos los usuarios,

<picture>
  <source
    srcset="
      company-photo-256w.webp   256w,
      company-photo-512w.webp   512w,
      company-photo-768w.webp   768w,
      company-photo-1024w.webp 1024w,
      company-photo-1280w.webp 1280w
    "
    type="image/webp"
  />
  <img
    srcset="
      company-photo-256w.jpg   256w,
      company-photo-512w.jpg   512w,
      company-photo-768w.jpg   768w,
      company-photo-1024w.jpg 1024w,
      company-photo-1280w.jpg 1280w
    "
    src="company-photo-256w.jpg"
    sizes="(min-width: 560px) 251px, 88.43vw"
    alt="The Sconnie Timber Staff!"
  />
</picture>

Pude reducirlo a lo siguiente en función de la compatibilidad con navegadores individuales:

<img
  src="/image/sizes:true/company-photo.jpg"
  sizes="(min-width: 560px) 251px, 88.43vw"
  alt="SAY CHEESY PICKLES."
/>

En este ejemplo, la URL /image es una secuencia de comandos de PHP seguida de parámetros que mod_rewrite vuelve a escribir. Toma un nombre de archivo de imagen y parámetros adicionales para ayudar a que una secuencia de comandos de backend elija la mejor imagen en las condiciones determinadas.

Supongo que tu primera pregunta es “¿Pero no es solo volver a implementar <picture> y srcset en el backend?”.

En cierto modo, sí, pero con una distinción importante: cuando una aplicación usa sugerencias del cliente para crear respuestas multimedia, la mayor parte (si no toda) del trabajo es mucho más fácil de automatizar, lo que puede incluir un servicio (como una CDN) que puede hacerlo en tu nombre. Mientras que, con las soluciones HTML, se debe escribir un nuevo marcado para proporcionar cada caso de uso. Por supuesto, puedes automatizar la generación de marcado. Sin embargo, si cambian tu diseño o requisitos, es probable que debas revisar tu estrategia de automatización en el futuro.

Las sugerencias del cliente permiten comenzar con una imagen de alta resolución sin pérdidas que luego se puede cambiar de tamaño de forma dinámica para que sea óptima para cualquier combinación de pantalla y diseño. A diferencia de srcset, que requiere que enumeres una lista fija de posibles imágenes candidatas para que el navegador elija, este enfoque puede ser más flexible. Si bien srcset te obliga a ofrecer a los navegadores un conjunto aproximado de variantes (por ejemplo, 256w, 512w, 768w y 1024w), una solución potenciada por sugerencias del cliente puede entregar todos los anchos, sin una gran cantidad de marcas.

Por supuesto, no tienes que escribir la lógica de selección de imágenes por tu cuenta. Cloudinary usa sugerencias del cliente para crear respuestas de imágenes cuando usas el w_autoparametro y observó que la mediana de los usuarios descargó un 42% menos de bytes cuando usó navegadores que admiten sugerencias del cliente.

Pero ten cuidado. Los cambios en la versión para computadoras de Chrome 67 quitaron la compatibilidad con los indicadores de cliente de origen cruzado. Por fortuna, estas restricciones no afectan a las versiones para dispositivos móviles de Chrome y se eliminarán por completo para todas las plataformas cuando se complete el trabajo en la política de funciones.

Ayuda a los usuarios con redes lentas

El rendimiento adaptable es la idea de que podemos ajustar la forma en que entregamos recursos según la información que nos proporcionan las sugerencias del cliente, en particular, la información sobre el estado actual de la conexión de red del usuario.

En el caso del sitio de Sconnie Timber, tomamos medidas para aligerar la carga cuando las redes son lentas, y se examinan los encabezados Save-Data, ECT, RTT y Downlink en nuestro código de backend. Cuando se hace esto, generamos una puntuación de calidad de la red que podemos usar para determinar si debemos intervenir para mejorar la experiencia del usuario. Esta puntuación de red está entre 0 y 1, donde 0 es la peor calidad de red posible y 1 es la mejor.

Inicialmente, verificamos si Save-Data está presente. Si es así, la puntuación se establece en 0, ya que suponemos que el usuario quiere que hagamos lo que sea necesario para que la experiencia sea más ligera y rápida.

Sin embargo, si no hay Save-Data, continuamos y ponderamos los valores de las sugerencias ECT, RTT y Downlink para calcular una puntuación que describa la calidad de la conexión de red. El código fuente de generación de puntuación de red está disponible en GitHub. La conclusión es que, si usamos las sugerencias relacionadas con la red de alguna manera, podemos mejorar las experiencias de quienes tienen redes lentas.

Comparación de un sitio que no usa sugerencias del cliente para adaptarse a una conexión de red lenta (izquierda) y el mismo sitio que sí lo hace (derecha).
Figura 2. Una página "Acerca de nosotros" para el sitio de una empresa local La experiencia del modelo de referencia incluye fuentes web, JavaScript para generar un carrusel y un comportamiento de acordeón, así como imágenes de contenido. Estas son todas las opciones que podemos omitir cuando las condiciones de la red son demasiado lentas para cargarlas rápidamente.

Cuando los sitios se adaptan a la información que proporcionan las sugerencias del cliente, no tenemos que adoptar un enfoque de “todo o nada”. Podemos decidir de forma inteligente qué recursos enviar. Podemos modificar nuestra lógica de selección de imágenes responsivas para enviar imágenes de menor calidad para una pantalla determinada y acelerar el rendimiento de carga cuando la calidad de la red es deficiente.

En este ejemplo, podemos ver el impacto que tienen las sugerencias del cliente a la hora de mejorar el rendimiento de los sitios en redes más lentas. A continuación, se muestra una cascada de WebPagetest de un sitio en una red lenta que no se adapta a las sugerencias del cliente:

Cascada de WebPagetest del sitio Sconnie Timber que carga todos los recursos en una conexión de red lenta.
Figura 3. Un sitio con muchos recursos que carga imágenes, secuencias de comandos y fuentes en una conexión lenta.

Y ahora, una cascada para el mismo sitio en la misma conexión lenta, excepto que esta vez el sitio usa sugerencias del cliente para eliminar los recursos de página no esenciales:

Una cascada de WebPagetest del sitio Sconnie Timber que usa sugerencias del cliente para decidir no cargar recursos no críticos en una conexión de red lenta.
Figura 4. El mismo sitio en la misma conexión, solo se excluyen los recursos “deseables” para una carga más rápida.

Las sugerencias del cliente redujeron el tiempo de carga de la página de más de 45 segundos a menos de una décima parte de ese tiempo. No se puede enfatizar lo suficiente los beneficios de las sugerencias del cliente en esta situación, ya que pueden ser una gran ventaja para los usuarios que buscan información fundamental en redes lentas.

Además, es posible usar sugerencias del cliente sin interrumpir la experiencia para los navegadores que no las admiten. Por ejemplo, si queremos ajustar la entrega de recursos usando el valor de la sugerencia ECT y, al mismo tiempo, entregar la experiencia completa para los navegadores que no son compatibles, podemos establecer el resguardo en un valor predeterminado de la siguiente manera:

// Set the ECT value to "4g" by default.
$ect = isset($_SERVER["HTTP_ECT"]) ? $_SERVER["HTTP_ECT"] : "4g";

Aquí, "4g" representa la conexión de red de mayor calidad que describe el encabezado ECT. Si inicializamos $ect en "4g", no se verán afectados los navegadores que no admiten sugerencias de cliente. ¡Habilitación por la victoria!

Ten en cuenta esas cachés.

Cada vez que cambies una respuesta en función de un encabezado HTTP, debes tener en cuenta cómo las cachés manejarán las recuperaciones futuras de ese recurso. El encabezado Vary es indispensable aquí, ya que asigna las entradas de caché al valor de los encabezados de solicitud que se le proporcionan. En pocas palabras, si modificas alguna respuesta según un encabezado de solicitud HTTP determinado, casi siempre debes incluir ese encabezado en Vary de la siguiente manera:

Vary: DPR, Width

Sin embargo, hay una gran salvedad: nunca debes Vary almacenar en caché las respuestas en un encabezado que cambia con frecuencia (como Cookie), ya que esos recursos dejan de poder almacenarse en caché. Con esto en mente, te recomendamos que evites Vary en los encabezados de sugerencias del cliente, como RTT o Downlink, ya que son factores de conexión que podrían cambiar con bastante frecuencia. Si deseas modificar las respuestas en esos encabezados, considera escribir solo el encabezado ECT, lo que minimizará las faltas de caché.

Por supuesto, esto solo se aplica si almacenas en caché una respuesta en primer lugar. Por ejemplo, no almacenarás en caché los recursos HTML si su contenido es dinámico, ya que eso puede dañar la experiencia del usuario en las visitas repetidas. En estos casos, no dudes en modificar esas respuestas en función de lo que consideres necesario y no te preocupes por Vary.

Sugerencias de clientes en los trabajadores del servicio

La negociación de contenido ya no es solo para los servidores. Dado que los trabajadores de servicio actúan como proxies entre los clientes y los servidores, tienes control sobre cómo se entregan los recursos a través de JavaScript. Esto incluye las sugerencias del cliente. En el evento fetch del trabajador de servicio, puedes usar el método request.headers.get del objeto event para leer los encabezados de solicitud de un recurso de la siguiente manera:

self.addEventListener('fetch', (event) => {
  let dpr = event.request.headers.get('DPR');
  let viewportWidth = event.request.headers.get('Viewport-Width');
  let width = event.request.headers.get('Width');

  event.respondWith(
    (async function () {
      // Do what you will with these hints!
    })(),
  );
});

Cualquier encabezado de sugerencia de cliente que habilites se puede leer de esta manera. Sin embargo, esa no es la única forma de obtener parte de esta información. Las sugerencias específicas de la red se pueden leer en estas propiedades de JavaScript equivalentes en el objeto navigator:

Sugerencia del cliente Equivalente de JS
"ECT" "navigator.connection.effectiveType"
"RTT" `navigator.connection.rtt`
"Save-Data" "navigator.connection.saveData"
"Downlink" "navigator.connection.downlink"
"Device-Memory" "navigator.deviceMemory"
Complementos de Imagemin para tipos de archivos.

Debido a que estas APIs no están disponibles en todas partes, debes verificar las funciones con el operador in:

if ('connection' in navigator) {
  // Work with netinfo API properties in JavaScript!
}

A partir de aquí, puedes usar una lógica similar a la que usarías en el servidor, excepto que no necesitas un servidor para negociar contenido con sugerencias del cliente. Solo los trabajadores de servicio tienen el poder de hacer que las experiencias sean más rápidas y resilientes debido a la capacidad adicional que tienen para entregar contenido cuando el usuario no tiene conexión.

Conclusión

Con las sugerencias del cliente, podemos hacer que las experiencias de los usuarios sean más rápidas de una manera completamente progresiva. Podemos publicar contenido multimedia según las capacidades del dispositivo del usuario de una manera que facilite la publicación de imágenes responsivas en lugar de depender de <picture> y srcset, en especial para casos de uso complejos. Esto nos permite no solo reducir el tiempo y el esfuerzo en el lado del desarrollo, sino también optimizar los recursos, en particular las imágenes, de una manera que se segmente para las pantallas de los usuarios de forma más precisa que y srcset.

Quizás lo más importante es que podemos detectar conexiones de red deficientes y cerrar la brecha para los usuarios modificando lo que enviamos y cómo lo hacemos. Esto puede ser muy útil para facilitar el acceso a los sitios para los usuarios en redes frágiles. En combinación con los service workers, podemos crear sitios increíblemente rápidos que están disponibles sin conexión.

Si bien las sugerencias para el cliente solo están disponibles en Chrome y en navegadores basados en Chromium, es posible usarlas de una manera que no afecte a los navegadores que no las admiten. Considera usar sugerencias de cliente para crear experiencias realmente inclusivas y adaptables que conozcan las capacidades del dispositivo de cada usuario y las redes a las que se conectan. Con suerte, otros proveedores de navegadores verán su valor y mostrarán la intención de implementarlos.

Recursos

Gracias a Ilya Grigorik, Eric Portis, Jeff Posnick, Yoav Weiss y Estelle Weyl por sus valiosos comentarios y ediciones en este artículo.