Presentamos la sincronización en segundo plano

Fecha de publicación: 8 de diciembre de 2015

La sincronización en segundo plano es una API web que te permite aplazar acciones hasta que el usuario tenga una conectividad estable. Esto te ayuda a permitir que los usuarios envíen los archivos que quieran lo antes posible.

Browser Support

  • Chrome: 89.
  • Edge: 89.
  • Firefox: not supported.
  • Safari: not supported.

Source

El problema

Internet es un gran lugar para perder el tiempo. Sin perder tiempo en Internet, no sabríamos que a los gatos no les gustan las flores, que a los camaleones les encantan las burbujas ni que Eric Bidelman es un héroe del minigolf de fines de los 90.

Pero, a veces, solo a veces, no queremos perder el tiempo. La experiencia del usuario ideal es más bien la siguiente:

  1. El teléfono está fuera del bolsillo.
  2. Alcanza un objetivo secundario.
  3. El teléfono está en el bolsillo.
  4. Reanudar la vida

Lamentablemente, esta experiencia se interrumpe con frecuencia debido a la mala conectividad. A todos nos ha pasado. Estás mirando una pantalla en blanco o un indicador de carga, y sabes que deberías rendirte y seguir con tu vida, pero esperas otros 10 segundos por si acaso. ¿Después de esos 10 segundos? Nada.

Pero ¿por qué rendirse ahora? Ya invertiste tiempo, por lo que irte sin nada sería un desperdicio, así que sigues esperando. En este punto, quieres rendirte, pero sabes que, en el segundo en que lo hagas, todo se habría cargado si tan solo hubieras esperado.

Los service workers resuelven la parte de carga de la página, ya que te permiten entregar contenido desde una caché. Pero, ¿qué sucede cuando la página necesita enviar algo al servidor?

Por el momento, si el usuario presiona "Enviar" en un mensaje, debe mirar un indicador de carga hasta que se complete. Si intentan salir o cerrar la pestaña, usamos onbeforeunload para mostrar un mensaje como "No, necesito que sigas mirando este spinner un poco más. Lo siento". Si el usuario no tiene conexión, le decimos: "Lo sentimos, debes volver más tarde y volver a intentarlo".

La sincronización en segundo plano te permite mejorar.

La solución

En el siguiente video, se muestra Emojoy, una demostración de chat solo con emojis. Es una app web progresiva que prioriza el uso sin conexión. La app usa mensajes y notificaciones push, y sincronización en segundo plano.

Si el usuario intenta enviar un mensaje cuando no tiene conectividad, afortunadamente, el mensaje se envía en segundo plano una vez que se conecta.

Poder enviar en segundo plano de esta manera también genera una mejora percibida en el rendimiento. La app no necesita hacer tanto alarde sobre el envío de mensajes, por lo que puede agregar el mensaje al resultado de inmediato.

La sincronización en segundo plano está disponible a partir de Chrome 49.

Cómo solicitar una sincronización en segundo plano

Al verdadero estilo de la Web extensible, esta es una función de bajo nivel que te brinda la libertad de hacer lo que necesites. Solicitas que se active un evento cuando el usuario tenga conectividad, lo que sucede de inmediato si el usuario ya tiene conectividad. Luego, escuchas ese evento y haces lo que necesites.

Al igual que la mensajería push, utiliza un service worker como destino del evento, lo que le permite funcionar cuando la página no está abierta. Para comenzar, regístrate para una sincronización desde una página:

// Register your service worker:
navigator.serviceWorker.register('/sw.js');

// Then later, request a one-off sync:
navigator.serviceWorker.ready.then(function(swRegistration) {
  return swRegistration.sync.register('myFirstSync');
});
 ```

Then listen for the event in `/sw.js`:

```js
self.addEventListener('sync', function(event) {
  if (event.tag == 'myFirstSync') {
    event.waitUntil(doSomeStuff());
  }
});

Eso es todo. doSomeStuff() debe devolver una promesa que indique el éxito o el fracaso de lo que intente hacer. Si se cumple, la sincronización se completa. Si falla, se programará otra sincronización para volver a intentarlo. Los reintentos de sincronización también esperan la conectividad y emplean una retirada exponencial.

El nombre de la etiqueta de la sincronización (“myFirstSync” en el ejemplo) debe ser único para una sincronización determinada. Si registras una sincronización con la misma etiqueta que una sincronización pendiente, se fusionará con la sincronización existente. Esto significa que puedes registrar una sincronización de "borrar la bandeja de salida" cada vez que el usuario envíe un mensaje, pero si envía 5 mensajes sin conexión, solo obtendrás una sincronización cuando se conecte. Para obtener 5 eventos de sincronización separados, usa etiquetas únicas.

Aquí tienes una demostración que usa el evento de sincronización para mostrar una notificación.

Usos de la sincronización en segundo plano

Lo ideal sería que lo uses para programar cualquier envío de datos que te interese más allá de la vida útil de la página. Mensajes de chat, correos electrónicos, actualizaciones de documentos, cambios de configuración, cargas de fotos o cualquier contenido que quieras que llegue al servidor, incluso si el usuario sale o cierra la pestaña. La página podría almacenar estos datos en un almacén de "bandeja de salida" en IndexedDB, y el service worker los recuperaría y los enviaría.

Aunque también podrías usarlo para recuperar pequeños fragmentos de datos.

Demostración de Wikipedia sin conexión

Esta es la demostración de Wikipedia sin conexión que creé para Supercharging Page Load. Desde entonces, le agregué algo de magia de sincronización en segundo plano.

Prueba lo siguiente:

  1. Mantén el navegador abierto en esta pestaña.
  2. Desactiva la conexión Wi-Fi o activa el modo avión para desconectarte.
  3. Haz clic en un vínculo a otro artículo.
  4. Se te indicará que no se pudo cargar la página (esto también aparecerá si la página tarda en cargarse).
  5. Aceptar las notificaciones
  6. Cierra el navegador.
  7. Conectarse
  8. Recibirás una notificación cuando el artículo se descargue, se almacene en caché y esté listo para leerse.

Con este patrón, el usuario puede guardar el teléfono en el bolsillo y seguir con su vida, sabiendo que el teléfono lo alertará cuando haya encontrado lo que buscaba.

Permisos

Las demostraciones que mostré usan notificaciones web, que requieren permiso, pero la sincronización en segundo plano en sí no.

Los eventos de sincronización suelen completarse mientras el usuario tiene una página abierta en el sitio, por lo que requerir el permiso del usuario sería una mala experiencia. En cambio, limitaremos cuándo se pueden registrar y activar las sincronizaciones para evitar abusos. Por ejemplo:

  • Solo puedes registrarte para un evento de sincronización cuando el usuario tiene una ventana abierta en el sitio.
  • El tiempo de ejecución de los eventos está limitado, por lo que no puedes usarlos para hacer ping a un servidor cada X segundos, extraer bitcoins ni nada por el estilo.

Por supuesto, estas restricciones pueden flexibilizarse o endurecerse según el uso en el mundo real.

Mejora progresiva

Mientras esperamos que la sincronización en segundo plano sea la base, puedes usarla como una mejora progresiva:

if ('serviceWorker' in navigator && 'SyncManager' in window) {
  navigator.serviceWorker.ready.then(function(reg) {
    return reg.sync.register('tag-name');
  }).catch(function() {
    // system was unable to register for a sync,
    // this could be an OS-level restriction
    postDataFromThePage();
  });
} else {
  // serviceworker/sync not supported
  postDataFromThePage();
}

Si los service workers o la sincronización en segundo plano no están disponibles, publica el contenido de la página como lo harías hoy.

Vale la pena usar la sincronización en segundo plano, incluso si parece que el usuario tiene buena conectividad, ya que te protege contra las navegaciones y los cierres de pestañas durante el envío de datos.

El futuro

Nuestro objetivo es lanzar la sincronización en segundo plano en una versión estable de Chrome en el primer semestre de 2016, mientras trabajamos en una variante, la "sincronización periódica en segundo plano". Con la sincronización periódica en segundo plano, puedes solicitar un evento restringido por intervalo de tiempo, estado de la batería y estado de la red. Por supuesto, esto requerirá el permiso del usuario, y también dependerá del navegador cuándo y con qué frecuencia se activarán estos eventos. En otras palabras, un sitio de noticias podría solicitar la sincronización cada hora, pero el navegador puede saber que solo lees ese sitio a las 7 a.m., por lo que la sincronización se activaría todos los días a las 6:50 a.m. Esta idea está un poco más lejos que la sincronización única, pero llegará.

Poco a poco, estamos incorporando patrones exitosos de Android y iOS a la Web, sin dejar de lado lo que la hace increíble.