Entrega de aplicaciones rápidas y ligeras con Save-Data

El encabezado de solicitud de sugerencias del cliente Save-Data, disponible en los navegadores Chrome, Yandex y Opera, permite a los desarrolladores ofrecer aplicaciones más livianas y rápidas a los usuarios que habilitan el modo de ahorro de datos en su navegador.

La necesidad de páginas ligeras

Estadísticas de Weblight

Todos coinciden en que las páginas web más rápidas y livianas proporcionan una experiencia del usuario más satisfactoria, permiten una mejor comprensión y retención del contenido, y generan mayores ingresos y conversiones. Una investigación de Google demostró que “... las páginas optimizadas se cargan cuatro veces más rápido que la original y usan un 80% menos de bytes. Debido a que estas páginas se cargan mucho más rápido, también observamos un aumento del 50% en el tráfico hacia ellas".

Además, aunque la cantidad de conexiones 2G finalmente disminuirá, la 2G todavía fue la tecnología de red dominante en 2015. La penetración y disponibilidad de las redes 3G y 4G están creciendo rápidamente, pero los costos de propiedad asociados y las restricciones de red siguen siendo un factor importante para cientos de millones de usuarios.

Estos son argumentos sólidos para la optimización de páginas.

Existen métodos alternativos para mejorar la velocidad del sitio sin la participación directa de los desarrolladores, como los navegadores proxy y los servicios de transcodificación. Si bien estos servicios son bastante populares, presentan desventajas importantes: compresión de imágenes y texto simple (y a veces inaceptable), incapacidad para procesar páginas seguras (HTTPS), optimización únicamente de las páginas visitadas mediante un resultado de la búsqueda y mucho más. La gran popularidad de estos servicios es un indicador de que los desarrolladores web no están abordando adecuadamente la alta demanda de los usuarios de aplicaciones y páginas rápidas y livianas. Pero alcanzar ese objetivo es un camino complejo y, a veces, difícil.

El encabezado de la solicitud Save-Data

Una técnica bastante sencilla es permitir que el navegador ayude con el encabezado de la solicitud Save-Data. Cuando se identifica este encabezado, una página web puede personalizar y ofrecer una experiencia del usuario optimizada a los usuarios con limitaciones de costo y rendimiento.

Los navegadores compatibles (a continuación) permiten al usuario habilitar un *modo de guardado de datos que le da permiso al navegador para aplicar un conjunto de optimizaciones a fin de reducir la cantidad de datos requeridos para renderizar la página. Cuando se expone o anuncia esta función, el navegador puede solicitar imágenes de menor resolución, aplazar la carga de algunos recursos o enrutar las solicitudes a través de un servicio que aplique otras optimizaciones específicas del contenido, como la compresión de imágenes y recursos de texto.

Navegadores compatibles

  • Chrome 49 y versiones posteriores anuncia Save-Data cuando el usuario habilita la opción "Ahorro de datos" en dispositivos móviles o la extensión "Ahorro de datos" en navegadores para computadoras.
  • Opera 35 y versiones posteriores anuncia Save-Data cuando el usuario habilita el modo "Opera Turbo" en computadoras de escritorio o la opción "Ahorro de datos" en navegadores Android.
  • Yandex 16.2 y versiones posteriores anuncia Save-Data cuando el modo Turbo está habilitado en computadoras de escritorio o navegadores para dispositivos móviles.

Detecta la configuración de Save-Data

Para determinar cuándo ofrecer la experiencia "ligera" a los usuarios, tu aplicación puede buscar el encabezado Save-Data de la solicitud de sugerencias del cliente. Este encabezado de solicitud indica la preferencia del cliente por reducir el uso de datos debido a los altos costos de transferencia, las velocidades de conexión lentas o cualquier otro motivo.

Cuando el usuario habilita el modo de ahorro de datos en su navegador, este agrega el encabezado de solicitud Save-Data a todas las solicitudes salientes (tanto HTTP como HTTPS). En el momento de la redacción de este documento, el navegador solo anuncia un token *on- en el encabezado (Save-Data: on), pero esto puede extenderse en el futuro para indicar otras preferencias del usuario.

Además, es posible detectar si Save-Data está activado en JavaScript:

if ('connection' in navigator) {
  if (navigator.connection.saveData === true) {
    // Implement data saving operations here.
  }
}

Es fundamental comprobar la presencia del objeto connection dentro del objeto navigator, ya que representa la API de Network Information, que solo se implementa en los navegadores Chrome, Chrome para Android y Samsung. A partir de ahí, solo debes verificar si navigator.connection.saveData es igual a true y puedes implementar cualquier operación de guardado de datos en esa condición.

El encabezado de Guardar datos que se revela en las Herramientas para desarrolladores de Chrome que se muestra junto con la extensión del Ahorro de datos
Habilitación de la extensión Ahorro de datos en la versión de escritorio de Chrome.

Si tu aplicación usa un service worker, puede inspeccionar los encabezados de la solicitud y aplicar la lógica relevante para optimizar la experiencia. De manera alternativa, el servidor puede buscar las preferencias anunciadas en el encabezado de la solicitud Save-Data y mostrar una respuesta alternativa: lenguaje de marcado diferente, imágenes y videos más pequeños, etcétera.

Sugerencias y prácticas recomendadas para la implementación

  1. Cuando uses Save-Data, proporciona algunos dispositivos de IU que lo admitan y permita a los usuarios alternar fácilmente entre experiencias. Por ejemplo:
    • Notifica a los usuarios que se admite Save-Data y anímalos a usarlo.
    • Permite que los usuarios identifiquen y elijan el modo con mensajes apropiados y botones o casillas de verificación intuitivos para activar o desactivar.
    • Cuando se seleccione el modo de ahorro de datos, anuncia y proporciona una manera fácil y obvia de inhabilitarlo y volver a la experiencia completa si lo deseas.
  2. Recuerda que las aplicaciones ligeras no son aplicaciones menores. No omiten funciones ni datos importantes, sino que tienen más en cuenta los costos involucrados y la experiencia del usuario. Por ejemplo:
    • Una aplicación de galería de fotos puede ofrecer vistas previas de menor resolución o usar un mecanismo de carrusel con menos código.
    • Una aplicación de búsqueda puede mostrar menos resultados a la vez, limitar la cantidad de resultados con mucho contenido multimedia o reducir la cantidad de dependencias necesarias para procesar la página.
    • Un sitio orientado a noticias puede mostrar menos noticias, omitir categorías menos populares o proporcionar vistas previas de medios más pequeñas.
  3. Proporciona la lógica del servidor para verificar el encabezado de la solicitud Save-Data y considera proporcionar una respuesta de página alternativa más ligera cuando esté habilitada; p.ej., reducir la cantidad de recursos y dependencias necesarios, aplicar una compresión de recursos más agresiva, etcétera.
    • Si entregas una respuesta alternativa basada en el encabezado Save-Data, recuerda agregarla a la lista Vary, Vary: Save-Data, para indicarles a las cachés ascendentes que deben almacenar en caché y entregar esta versión solo si el encabezado de la solicitud Save-Data está presente. Para obtener más detalles, consulta las prácticas recomendadas para la interacción con cachés.
  4. Si usas un service worker, tu aplicación puede detectar cuándo está habilitada la opción de guardar datos. Para ello, verifica la presencia del encabezado de la solicitud Save-Data o el valor de la propiedad navigator.connection.saveData. Si se habilita, considera si puedes reescribir la solicitud para recuperar menos bytes o usar una respuesta ya recuperada.
  5. Considera aumentar Save-Data con otros indicadores, como la información sobre la tecnología y el tipo de conexión del usuario (consulta la API de NetInfo). Por ejemplo, es posible que quieras entregar la experiencia liviana a cualquier usuario en una conexión 2G, incluso si Save-Data no está habilitado. Por el contrario, que el usuario tenga una conexión 4G "rápida" no significa que no esté interesado en guardar datos, por ejemplo, en roaming. Además, puedes aumentar la presencia de Save-Data con la sugerencia de cliente Device-Memory para adaptarte aún más a los usuarios que usan dispositivos con memoria limitada. La memoria del dispositivo del usuario también se anuncia en la sugerencia de cliente navigator.deviceMemory.

Plantillas

Lo que puedes lograr con Save-Data se limita solo a lo que puedes inventar. Para que tengas una idea de lo que es posible, analicemos algunos casos de uso. Es posible que se te ocurran otros casos de uso a medida que leas esto, así que no dudes en experimentar y ver lo que puedes hacer.

Buscando Save-Data en el código del servidor

Si bien el estado Save-Data es algo que puedes detectar en JavaScript a través de la propiedad navigator.connection.saveData, a veces es preferible detectarlo en el servidor. En algunos casos, es posible que JavaScript falle. Además, la detección del servidor es la única forma de modificar el lenguaje de marcado antes de que se envíe al cliente, lo cual forma parte de algunos de los casos de uso más beneficiosos de Save-Data.

La sintaxis específica para detectar el encabezado Save-Data en el código del servidor depende del lenguaje utilizado, pero la idea básica debe ser la misma para cualquier backend de la aplicación. Por ejemplo, en PHP, los encabezados de las solicitudes se almacenan en el arreglo superglobal $_SERVER en los índices que comienzan con HTTP_. Esto significa que puedes detectar el encabezado Save-Data si verificas la existencia y el valor de la variable $_SERVER["HTTP_SAVE_DATA"] de la siguiente manera:

// false by default.
$saveData = false;

// Check if the `Save-Data` header exists and is set to a value of "on".
if (isset($_SERVER["HTTP_SAVE_DATA"]) && strtolower($_SERVER["HTTP_SAVE_DATA"]) === "on") {
  // `Save-Data` detected!
  $saveData = true;
}

Si colocas esta verificación antes de que se envíe cualquier lenguaje de marcado al cliente, la variable $saveData contendrá el estado Save-Data y estará disponible en cualquier lugar de la página para su uso. Con este mecanismo ilustrado, veamos algunos ejemplos de cómo se puede usar para limitar la cantidad de datos que enviamos al usuario.

Publica imágenes de baja resolución para pantallas de alta resolución

Un caso de uso común para imágenes en la Web implica entregar imágenes en conjuntos de dos: una imagen para pantallas "estándar" (1x) y otra imagen con el doble de tamaño (2x) para pantallas de alta resolución (p.ej., Retina Display). Esta clase de pantallas de alta resolución no se limita necesariamente a los dispositivos de alta gama y es cada vez más común. En los casos en los que se prefiere una experiencia de aplicación más liviana, podría ser prudente enviar imágenes de menor resolución (1x) a estas pantallas, en lugar de variantes más grandes (2x). Para lograrlo cuando el encabezado Save-Data esté presente, simplemente modificamos el lenguaje de marcado que enviamos al cliente:

if ($saveData === true) {
  // Send a low-resolution version of the image for clients specifying `Save-Data`.
  ?><img src="butterfly-1x.jpg" alt="A butterfly perched on a flower."><?php
}
else {
  // Send the usual assets for everyone else.
  ?><img src="butterfly-1x.jpg" srcset="butterfly-2x.jpg 2x, butterfly-1x.jpg 1x" alt="A butterfly perched on a flower."><?php
}

Este caso de uso es un ejemplo perfecto de lo poco esfuerzo que se requiere para adaptarte a alguien que te pide específicamente que le envíes menos datos. Si no quieres modificar el lenguaje de marcado en el backend, también puedes lograr el mismo resultado mediante un módulo de reescritura de URL, como mod_rewrite de Apache. Hay ejemplos de cómo lograr esto con relativamente poca configuración.

También puedes extender este concepto a las propiedades background-image de CSS con solo agregar una clase al elemento <html>:

<html class="<?php if ($saveData === true): ?>save-data<?php endif; ?>">

Desde aquí, puedes orientar la clase save-data en el elemento <html> de tu CSS para cambiar la forma en que se entregan las imágenes. Puedes enviar imágenes de fondo de baja resolución a pantallas de alta resolución como se muestra en el ejemplo de HTML anterior, o bien omitir ciertos recursos por completo.

Omite imágenes no esenciales

Parte del contenido de imágenes de la Web es simplemente no esencial. Si bien esas imágenes pueden ser útiles para el contenido, es posible que no les resulte conveniente a quienes intenten sacar todo lo que puedan de los planes de datos medidos. En el caso de uso quizás más simple de Save-Data, podemos usar el código de detección PHP de antes y omitir por completo el lenguaje de marcado de imágenes no esenciales:

<p>This paragraph is essential content. The image below may be humorous, but it's not critical to the content.</p>
<?php
if ($saveData === false) {
  // Only send this image if `Save-Data` hasn't been detected.
  ?><img src="meme.jpg" alt="One does not simply consume data."><?php
}

Sin duda, esta técnica puede tener un efecto pronunciado, como se puede observar en la siguiente figura:

Es una comparación de las imágenes no críticas que se cargan cuando la función Save-Data no está presente, en comparación con las mismas imágenes que se omiten cuando Save-Data está presente.
Es una comparación de las imágenes no críticas que se cargan cuando la función Guardar datos está ausente, con la que se omiten cuando la función Guardar datos está presente.

Por supuesto, omitir imágenes no es la única posibilidad. También puedes actuar en Save-Data para no enviar otros recursos que no sean críticos, como ciertos tipos de letra.

Omite las fuentes web no esenciales

Si bien las fuentes web no suelen representar casi tanto de la carga útil total de una página como las imágenes, siguen siendo muy populares. Tampoco consumen una cantidad insignificante de datos. Además, la forma en que los navegadores recuperan y renderizan fuentes es más complicada de lo que crees, con conceptos como FOIT, FOUT y la heurística del navegador que hacen que la renderización sea una operación con matices.

Por lo tanto, es posible que quieras omitir las fuentes web no esenciales para los usuarios que quieren experiencias del usuario más eficientes. Save-Data hace que esto sea razonablemente indoloro.

Por ejemplo, supongamos que incluiste Fira Sans de Google Fonts en tu sitio. Fira Sans es una excelente fuente para el texto del cuerpo, pero quizá no sea tan importante para los usuarios que intentan guardar datos. Si se agrega una clase de save-data al elemento <html> cuando el encabezado Save-Data está presente, se pueden escribir estilos que invoquen el tipo de letra no esencial al principio, pero que luego se inhabiliten cuando el encabezado Save-Data esté presente:

/* Opt into web fonts by default. */
p,
li {
  font-family: 'Fira Sans', 'Arial', sans-serif;
}

/* Opt out of web fonts if the `save-Data` class is present. */
.save-data p,
.save-data li {
  font-family: 'Arial', sans-serif;
}

Con este enfoque, puedes dejar el fragmento <link> de Google Fonts en su lugar, ya que el navegador carga especulativamente los recursos de CSS (incluidas las fuentes web), primero aplicando diseños al DOM y, luego, verificando si algún elemento HTML invoca alguno de los recursos de la hoja de estilo. Si alguien pasa con Save-Data activado, Fira Sans nunca se cargará porque el DOM con estilo nunca lo invocará. En su lugar, se iniciará Arial. No es tan agradable como Fira Sans, pero puede ser preferible a aquellos usuarios que tratan de ampliar sus planes de datos.

Resumen

El encabezado Save-Data no tiene muchos matices; está activado o desactivado, y la aplicación tiene la responsabilidad de proporcionar experiencias adecuadas en función de su configuración, independientemente del motivo.

Por ejemplo, es posible que algunos usuarios no permitan el modo de ahorro de datos si sospechan que se perderá el contenido o la función de la app, incluso si tienen mala conectividad. Por el contrario, algunos usuarios podrían habilitar esta opción para mantener las páginas lo más pequeñas y sencillas posible, incluso en una buena situación de conectividad. Es mejor que tu app suponga que el usuario desea la experiencia completa e ilimitada hasta que tengas una indicación clara mediante una acción explícita del usuario.

Como propietarios de sitios y desarrolladores web, asumamos la responsabilidad de administrar nuestro contenido para mejorar la experiencia del usuario con datos y usuarios limitados.

Para obtener más detalles sobre Save-Data y excelentes ejemplos prácticos, consulta Ayuda a tus usuarios Save Data.