API de Device Memory

Hoy en día, la variedad de capacidades de los dispositivos que pueden conectarse a la Web es más amplia que nunca. La misma aplicación web que se entrega a una computadora de escritorio de alta gama también se puede entregar a un teléfono, reloj o tablet de baja potencia, y puede resultar muy difícil crear experiencias atractivas que funcionen sin problemas en cualquier dispositivo.

La API de Device Memory es una nueva función de plataforma web que tiene como objetivo ayudar a los desarrolladores web a lidiar con el entorno moderno de los dispositivos. Agrega una propiedad de solo lectura al objeto navigator, navigator.deviceMemory, que muestra cuánta RAM tiene el dispositivo en gigabytes, redondeada hacia abajo a la potencia de dos más cercana. La API también presenta un encabezado de Client Hints, Device-Memory, que informa el mismo valor.

La API de Device Memory les brinda a los desarrolladores la capacidad de realizar dos tareas principales:

  • Toma decisiones durante el tiempo de ejecución sobre qué recursos entregar en función del valor de memoria del dispositivo que se muestra (p.ej., entrega una versión "lite" de una app a los usuarios que tienen dispositivos con poca memoria).
  • Informa este valor a un servicio de estadísticas para que puedas comprender mejor cómo la memoria del dispositivo se correlaciona con el comportamiento de los usuarios, las conversiones y otras métricas importantes para tu negocio.

Cómo adaptar el contenido de forma dinámica en función de la memoria del dispositivo

Si ejecutas tu propio servidor web y puedes modificar la lógica que entrega los recursos, puedes responder condicionalmente a las solicitudes que contengan el Client Hints Header Device-Memory.

GET /main.js HTTP/1.1
Host: www.example.com
Device-Memory: 0.5
Accept: */*

Con esta técnica, puedes crear una o más versiones de las secuencias de comandos de tu aplicación y responder a las solicitudes del cliente de forma condicional según el valor establecido en el encabezado Device-Memory. No es necesario que estas versiones contengan un código completamente diferente (ya que es más difícil de mantener). La mayoría de las veces, la versión "lite" solo excluirá funciones que pueden ser costosas y no críticas para la experiencia del usuario.

Usa el encabezado de Client Hints

Para habilitar el encabezado Device-Memory, agrega la etiqueta <meta> de Client Hints al <head> de tu documento:

<meta http-equiv="Accept-CH" content="Device-Memory">

También puedes incluir "Device-Memory" en los encabezados de respuesta Accept-CH de tu servidor:

HTTP/1.1 200 OK
Date: Thu Dec 07 2017 11:44:31 GMT
Content-Type: text/html
Accept-CH: Device-Memory, Downlink, Viewport-Width

Esto le indica al navegador que envíe el encabezado Device-Memory con todas las solicitudes de los subrecursos para la página actual.

En otras palabras, una vez que hayas implementado una de las opciones anteriores para tu sitio web, si un usuario visita desde un dispositivo con 0.5 GB de RAM, todas las solicitudes de imágenes, CSS y JavaScript de esta página incluirán el encabezado Device-Memory con el valor establecido en "0.5", y tu servidor puede responder a esas solicitudes de la forma que creas conveniente.

Por ejemplo, la siguiente ruta Express entrega una versión "lite" de una secuencia de comandos si se establece el encabezado Device-Memory y su valor es menor que 1, o bien entrega una versión "completa" si el navegador no admite el encabezado Device-Memory, o si el valor es 1 o mayor:

app.get('/static/js/:scriptId', (req, res) => {
  // Low-memory devices should load the "lite" version of the component.
  // The logic below will set `scriptVersion` to "lite" if (and only if)
  // `Device-Memory` isn't undefined and returns a number less than 1.
  const scriptVersion = req.get('Device-Memory') < 1 ? 'lite' : 'full';

  // Respond with the file based on `scriptVersion` above.
  res.sendFile(`./path/to/${req.params.scriptId}.${scriptVersion}.js`);
});

Usa la API de JavaScript

En algunos casos (como con un servidor de archivos estáticos o una CDN), no podrás responder de forma condicional a las solicitudes basadas en un encabezado HTTP. En esos casos, puedes usar la API de JavaScript para realizar solicitudes condicionales en tu código JavaScript.

La siguiente lógica es similar a la ruta Express anterior, excepto que determina de forma dinámica la URL de la secuencia de comandos en la lógica del cliente:

// Low-memory devices should load the "lite" version of the component.
// The logic below will set `componentVersion` to "lite" if (and only if)
// deviceMemory isn't undefined and returns a number less than 1.
const componentVersion = navigator.deviceMemory < 1 ? 'lite' : 'full';

const component = await import(`path/to/component.${componentVersion}.js`);
component.init();

Si bien entregar condicionalmente diferentes versiones del mismo componente según las capacidades del dispositivo es una buena estrategia, a veces puede ser incluso mejor no entregar un componente en absoluto.

En muchos casos, los componentes son puramente mejoras. Agregan algunos toques agradables a la experiencia, pero no son necesarios para la funcionalidad principal de la app. En estos casos, puede ser conveniente no cargar esos componentes. Si un componente destinado a mejorar la experiencia del usuario provoca que la app sea lenta o no responda, significa que no se está cumpliendo su objetivo.

Con cualquier decisión que tomes que afecte la experiencia del usuario, es fundamental que midas su impacto. También es fundamental que tengas un panorama claro del rendimiento actual de tu app.

Comprender cómo se correlaciona la memoria del dispositivo con el comportamiento del usuario en la versión actual de tu app informará mejor las acciones que se deben tomar y te proporcionará un modelo de referencia con el que podrás medir el éxito de los cambios futuros.

Realiza un seguimiento de la memoria del dispositivo con estadísticas

La API de Device Memory es nueva, y la mayoría de los proveedores de estadísticas no realizan un seguimiento de ella de forma predeterminada. Afortunadamente, la mayoría de los proveedores de estadísticas te brindan una manera de hacer un seguimiento de los datos personalizados (por ejemplo, Google Analytics tiene una función llamada Dimensiones personalizadas) que puedes usar para hacer un seguimiento de la memoria de los dispositivos de tus usuarios.

Cómo usar una dimensión de memoria del dispositivo personalizada

El uso de dimensiones personalizadas en Google Analytics es un proceso de dos pasos.

  1. Configura la dimensión personalizada en Google Analytics.
  2. Actualiza tu código de seguimiento a set el valor de memoria del dispositivo para la dimensión personalizada que acabas de crear.

Cuando crees la dimensión personalizada, asígnale el nombre "Memoria del dispositivo" y elige un alcance de "sesión", ya que el valor no cambiará durante el transcurso de la sesión de navegación del usuario:

Cómo crear dimensiones personalizadas de memoria del dispositivo en Google Analytics
Cómo crear dimensiones personalizadas de memoria del dispositivo en Google Analytics

A continuación, actualiza el código de seguimiento. Este es un ejemplo de cómo podría ser. Ten en cuenta que, para los navegadores que no admiten la API de Device Memory, el valor de la dimensión será "(not set)".

// Create the tracker from your tracking ID.
// Replace "UA-XXXXX-Y" with your Google Analytics tracking ID.
ga('create', 'UA-XXXXX-Y', 'auto');

// Set the device memory value as a custom dimension on the tracker.
// This will ensure it gets sent with all future data to Google Analytics.
// Note: replace "XX" with the index of the custom dimension you created
// in the Google Analytics admin.
ga('set', 'dimensionXX', navigator.deviceMemory || '(not set)');

// Do any other other custom setup you want...

// Send the initial pageview.
ga('send', 'pageview');

Informes sobre los datos de memoria del dispositivo

Una vez que la dimensión de memoria del dispositivo sea set en el objeto de seguimiento, todos los datos que envíes a Google Analytics incluirán este valor. Esto te permitirá desglosar cualquier métrica que desees (p.ej., tiempos de carga de la página, tasa de finalización de objetivos, etc.) por memoria del dispositivo para ver si hay alguna correlación.

Dado que la memoria del dispositivo es una dimensión personalizada en lugar de una dimensión integrada, no la verás en ninguno de los informes estándares. Para acceder a estos datos, deberás crear un informe personalizado. Por ejemplo, la configuración de un informe personalizado que compara los tiempos de carga por memoria del dispositivo podría tener el siguiente aspecto:

Cómo crear un informe personalizado de memoria del dispositivo en Google Analytics
Cómo crear un informe personalizado de memoria del dispositivo en Google Analytics

Y el informe que genera podría verse de la siguiente manera:

Informe de memoria del dispositivo
Informe de memoria del dispositivo

Una vez que recopiles datos de la memoria del dispositivo y tengas un modelo de referencia sobre cómo los usuarios experimentan tu aplicación en todos los rangos del espectro de memoria, puedes experimentar con la entrega de diferentes recursos a diferentes usuarios (con las técnicas que se describen en la sección anterior). Posteriormente, podrás ver los resultados y ver si han mejorado.

Conclusión

En esta publicación, se describe cómo usar la API de Device Memory para adaptar tu aplicación a las capacidades de los dispositivos de tus usuarios y se muestra cómo medir la experiencia de estos usuarios.

Si bien esta publicación se enfoca en la API de Device Memory, la mayoría de las técnicas que se describen aquí se podrían aplicar a cualquier API que informe sobre las capacidades del dispositivo o las condiciones de la red.

A medida que el panorama de los dispositivos sigue expandiéndose, es más importante que nunca que los desarrolladores web consideren a todo el espectro de usuarios cuando tomen decisiones que afecten su experiencia.