Adapta la app a usuarios con Client Hints

Desarrollar sitios que sean rápidos en todas partes puede ser una tarea difícil. La gran cantidad de capacidades 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 de qué es capaz el dispositivo del usuario o cuál es la calidad de su conexión de red? La solución son las pistas del cliente.

Las sugerencias del cliente son un conjunto de encabezados de solicitud HTTP opcionales que nos brindan información sobre estos aspectos del dispositivo del usuario y la red a la que está conectado. Al acceder a esta información del servidor, podemos cambiar cómo entregamos el contenido según las condiciones del dispositivo o la red. Esto nos puede ayudar 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 cambiar las respuestas de contenido según los encabezados de solicitud del navegador.

Un ejemplo de negociación de contenido involucra el encabezado de la solicitud Accept. Describe los tipos de contenido que comprende el navegador, que el servidor puede usar para negociar la respuesta. Para 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 críticos 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 adecuada para los usuarios.

Cómo habilitarlo

A diferencia del encabezado Accept, las sugerencias del cliente no aparecen mágicamente (con la excepción de Save-Data, que analizaremos más adelante). Para mantener los encabezados de solicitud al mínimo, deberás habilitar las sugerencias del cliente que desees 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 separada por comas de las sugerencias solicitadas que el sitio usará para determinar los resultados de la solicitud de recursos posterior. Cuando el cliente lee este encabezado, se le indica que "este sitio quiere las sugerencias del cliente Viewport-Width y Downlink". No te preocupes por las sugerencias específicas. Hablaremos de eso en un momento.

Puedes establecer estos encabezados de habilitación en cualquier lenguaje de backend. Por ejemplo, se podría usar la función header de PHP. Incluso puedes establecer estos encabezados de aceptació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 dos cosas: el dispositivo que usan tus usuarios y la red que utilizan para acceder a tu sitio. Veamos brevemente todas las sugerencias disponibles.

Sugerencias de dispositivos

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

Antes de comenzar con la lista, puede ser útil conocer algunos términos clave que se usan para describir la resolución de pantallas y 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 de medios después de que se corrigió su 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 lenguaje de 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 de la imagen 2x es de 640 x 480. Si un cliente instalado en un dispositivo con una relación de píxeles del dispositivo de pantalla de 2 (p.ej., una pantalla Retina) analiza este lenguaje de 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 aplican 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 x 192.

Ilustración comparativa del tamaño intrínseco y el tamaño extrínseco. Se muestra un cuadro de 320 x 240 píxeles con la etiqueta TAMAÑO INTRÍNSECO. Dentro de él, hay un cuadro más pequeño de 256 × 192 píxeles, que representa un elemento img de HTML con CSS aplicado. Esta caja está etiquetada como EXTRINSIC SIZE. A la derecha, hay un cuadro que contiene el código 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 de tamaño intrínseco versus extrínseco. Una imagen adquiere 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 con un tamaño intrínseco de 320 x 240 en una con un tamaño extrínseco de 256 x 192.

Ahora que conocemos algunos términos, veamos la lista de sugerencias del cliente específicas del dispositivo que tienes disponibles.

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 ofrecer diferentes tratamientos (es decir, recortes) de una imagen que sean óptimos para tamaños de pantalla específicos (es decir, dirección de arte) o para omitir recursos que no sean necesarios para el ancho de pantalla actual.

DPR

DPR, abreviatura de relación de píxeles del dispositivo, informa la proporción de píxeles físicos en relación con los píxeles 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 imágenes 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 CSS de ancho y 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 gráfica para todos los tamaños de pantalla). Si se habilitó la sugerencia Width, el cliente enviará esta sugerencia Width al servidor con la solicitud del src del <img>:

Width: 544

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

Esta sugerencia es especialmente útil porque no solo tiene en cuenta el ancho de la pantalla corregido por densidad, 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 tanto para la pantalla como para 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 más simples de selección de recursos, las relaciones de píxeles entre los dispositivos y los recursos pueden ser las mismas. ¡Pero! En los casos en que se utilizan los encabezados DPR y Width, el tamaño extrínseco de un recurso puede generar situaciones en las que ambos difieran. 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 deben usar los servidores, 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 seleccionado] / ([Width] / [DPR])

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

Device-Memory

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

Device-Memory: 2

Un posible caso de uso de 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 consume y que los navegadores suelen cargar. También puedes enviar imágenes con un DPR más bajo, ya que usan menos memoria para decodificarse.

Sugerencias de red

La API de Network Information proporciona otra categoría de sugerencias del 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. La sugerencia RTT, a diferencia del RTT de la capa de transporte, incluye el tiempo de procesamiento del servidor.

RTT: 125

Esta sugerencia es útil debido al papel que desempeña la latencia en el rendimiento de carga. Con la sugerencia RTT, podemos tomar decisiones basadas en 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 influye. La sugerencia Downlink, expresada en megabits por segundo (Mbps), revela la velocidad de descarga aproximada de la conexión del usuario:

Downlink: 2.5

En conjunto 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 indica si tu puerta de enlace es una torre de telefonía 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 una red lenta a través de Wi-Fi, es posible que ECT se complete 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, se puede refinar 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 cosas que harías con ella son similares a otras sugerencias de red. Es posible que los usuarios también lo habiliten en entornos con alta latencia o poco ancho de banda. Cuando está presente, esta sugerencia siempre se ve de la siguiente manera:

Save-Data: on

En Google, hablamos sobre lo que puedes hacer con Save-Data. El impacto que puede tener en el rendimiento puede ser profundo. Es un indicador que muestra que los usuarios te piden literalmente que les envíes menos contenido. Si escuchas y actúas en función de ese indicador, los usuarios lo agradecerán.

Cómo juntar las piezas

Lo que hagas con las sugerencias del cliente depende de ti. Como ofrecen tanta información, tienes muchas opciones. Para que fluyan las ideas, veamos qué pueden hacer las sugerencias del cliente por Sconnie Timber, una empresa maderera ficticia ubicada en la zona rural del Medio Oeste superior. Como suele suceder en las áreas remotas, las conexiones de red pueden ser inestables. Aquí es donde una tecnología como las sugerencias del cliente puede marcar una gran diferencia para los usuarios.

Imágenes responsivas

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

Si bien <picture> y srcset son herramientas increíbles, sin duda, pueden llevar mucho tiempo desarrollarlas y mantenerlas 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 brindan.

Las sugerencias del cliente pueden simplificar este proceso. 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 con dirección de arte) marcando la sugerencia Viewport-Width.
  2. Selecciona una resolución de imagen. Para ello, consulta las sugerencias Width y DPR, y elige una fuente que se ajuste al tamaño del diseño y a la densidad de la pantalla de la imagen (de manera similar a cómo funcionan los descriptores x y w en srcset).
  3. Selecciona el formato de archivo más óptimo que admite 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 lenguaje de marcado a todos los usuarios, se enviaba lo siguiente:

<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 según 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 reescritos por mod_rewrite. Toma un nombre de archivo de imagen y parámetros adicionales para ayudar a una secuencia de comandos de backend a elegir la mejor imagen en las condiciones dadas.

Supongo que tu primera pregunta es "Pero ¿no es esto solo una reimplementación de <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 elaborar respuestas de medios, la mayor parte del trabajo (si no todo) es mucho más fácil de automatizar, lo que puede incluir un servicio (como una CDN) que puede hacer esto en tu nombre. Mientras que, con las soluciones HTML, se debe escribir un nuevo lenguaje de marcado para cada caso de uso. Claro que puedes automatizar la generación de marcas. Sin embargo, si cambian tus requisitos o diseño, 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 y sin pérdida 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 publicar todos los anchos sin una gran cantidad de marcado.

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 parámetro w_auto, y observó que los usuarios promedio descargaron un 42% menos de bytes cuando usaron navegadores que admiten sugerencias del cliente.

Pero ten cuidado. Los cambios en la versión para computadoras de Chrome 67 quitaron la compatibilidad con las sugerencias del cliente de origen cruzado. Afortunadamente, estas restricciones no afectan 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 Feature Policy.

Ayuda a los usuarios en redes lentas

El rendimiento adaptable se basa en la idea de que podemos ajustar la forma en que entregamos los recursos según la información que las sugerencias del cliente ponen a nuestra disposición, específicamente 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 esto sucede, 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 se encuentra 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 todo lo necesario para que la experiencia sea más ligera y rápida.

Sin embargo, si Save-Data no está presente, 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 la generación de la 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 usan 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 un sitio de empresa local. La experiencia de referencia incluye fuentes web, JavaScript para controlar el comportamiento de un carrusel y un acordeón, y también imágenes de contenido. Todos estos elementos se pueden omitir cuando las condiciones de la red son demasiado lentas para cargarlos 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, así, acelerar el rendimiento de carga cuando la calidad de la red es baja.

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

Una cascada de WebPagetest del sitio de 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 no críticos de la página:

Una cascada de WebPagetest del sitio de 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 que se excluyen los recursos “agradables” en favor de 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. Los beneficios de las sugerencias del cliente en este caso no se pueden enfatizar lo suficiente y pueden ser una gran ventaja para los usuarios que buscan información crítica en redes lentas.

Además, es posible usar sugerencias del cliente sin interrumpir la experiencia de 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, ofrecer la experiencia completa para los navegadores que no admiten la sugerencia, podemos establecer un valor predeterminado de resguardo 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", los navegadores que no admitan sugerencias del cliente no se verán afectados. ¡Habilita la opción para ganar!

¡Ten cuidado con las cachés!

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

Vary: DPR, Width

Sin embargo, hay una salvedad importante: Nunca debes almacenar en caché las respuestas Vary en un encabezado que cambia con frecuencia (como Cookie), ya que esos recursos se vuelven efectivamente no almacenables en caché. Con esta información, es posible que desees evitar 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 incluir solo el encabezado ECT, lo que minimizará las fallas de caché.

Por supuesto, esto solo se aplica si almacenas en caché una respuesta. Por ejemplo, no almacenarás en caché los recursos HTML si su contenido es dinámico, ya que eso puede afectar la experiencia del usuario en visitas repetidas. En estos casos, puedes modificar las respuestas según lo consideres necesario y no preocuparte por Vary.

Sugerencias del cliente en Service Workers

La negociación de contenido ya no es solo para servidores. Dado que los service workers 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 service worker, puedes usar el método request.headers.get del objeto event para leer los encabezados de la 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 del 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 en 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 archivo.

Como estas APIs no están disponibles en todas partes, debes verificar la función con el operador in:

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

Desde 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. Los service workers por sí solos tienen la capacidad de hacer que las experiencias sean más rápidas y resistentes gracias a la capacidad adicional que tienen para publicar contenido cuando el usuario está sin conexión.

Conclusión

Con las sugerencias del cliente, podemos hacer que las experiencias sean más rápidas para los usuarios de una manera completamente progresiva. Podemos publicar contenido multimedia en función de las capacidades del dispositivo del usuario de una manera que facilita la publicación de imágenes responsivas en comparación con el uso de <picture> y srcset, especialmente para casos de uso complejos. Esto nos permite no solo reducir el tiempo y el esfuerzo del desarrollo, sino también optimizar los recursos, en particular las imágenes, de una manera que se dirige a las pantallas de los usuarios con mayor precisión que y srcset.

Quizás lo más importante es que podemos detectar conexiones de red deficientes y reducir la brecha para los usuarios modificando lo que enviamos y cómo lo enviamos. Esto puede ser de gran ayuda para que los usuarios con redes inestables puedan acceder a los sitios con mayor facilidad. Si se combinan con los service workers, podemos crear sitios increíblemente rápidos que estén disponibles sin conexión.

Si bien las sugerencias del cliente solo están disponibles en Chrome y en los navegadores basados en Chromium, es posible usarlas de una manera que no dificulte el uso de los navegadores que no las admiten. Considera usar sugerencias del cliente para crear experiencias verdaderamente inclusivas y adaptables que tengan en cuenta las capacidades del dispositivo de cada usuario y las redes a las que se conectan. Esperamos que otros proveedores de navegadores vean el valor de estas APIs y muestren su intención de implementarlas.

Recursos

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