La sincronización en segundo plano es una nueva API web que te permite aplazar las acciones hasta que el usuario tenga una conectividad estable. Esto garantiza que se envíe lo que el usuario quiera enviar.
El problema
Internet es un gran lugar para perder el tiempo. Si no perdiéramos tiempo en Internet, no sabríamos que a los gatos no les gustan las flores, que a los camaleones les encantan las burbujas o que nuestro propio Eric Bidelman es un héroe del golf de minigolf de finales de los 90.
Pero, a veces, no queremos perder el tiempo. La experiencia del usuario óptima es más como la siguiente:
- Teléfono fuera del bolsillo.
- Lograr un objetivo menor
- El teléfono vuelve al bolsillo.
- Reanudar la vida.
Lamentablemente, esta experiencia se interrumpe con frecuencia debido a la conectividad deficiente. A todos nos ha pasado. Estás mirando una pantalla blanca o un ícono giratorio, y sabes que deberías rendirte y seguir con tu vida, pero le das otros 10 segundos por si acaso. ¿Después de esos 10 segundos? Nada.
Pero ¿por qué rendirte ahora? Ya invertiste tiempo, así que sería un desperdicio irte sin nada, así que sigues esperando. En este punto, quieres rendirte, pero sabes que el segundo que lo hagas será el segundo antes de que todo se cargue si solo hubieras esperado.
Los servicios en segundo plano 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?
En este momento, si el usuario presiona "Enviar" en un mensaje, debe mirar una lista de opciones hasta que se complete. Si intenta salir de la página o cerrar la pestaña, usamos onbeforeunload
para mostrar un mensaje como "No, necesito que mires este ícono giratorio un poco más. Lo siento". Si el usuario no tiene conexión, le decimos: "Lo siento, debes volver más tarde y volver a intentarlo".
Esto es una tontería. La sincronización en segundo plano te permite hacer más.
La solución
En el siguiente video, se muestra Emojoy, una demostración de chat solo con emojis. Es una app web progresiva y funciona primero sin conexión. La app usa notificaciones y mensajes push, y sincronización en segundo plano.
Si el usuario intenta enviar un mensaje cuando no tiene conectividad, el mensaje se envía en segundo plano una vez que se establece la conectividad.
A partir de marzo de 2016, la sincronización en segundo plano está disponible en Chrome a partir de la versión 49. Para ver cómo funciona, sigue estos pasos:
- Abre Emojoy.
- Desconecta el dispositivo (ya sea con el modo de avión o visita tu jaula de Faraday local).
- Escribe un mensaje.
- Regresa a la pantalla principal (opcionalmente, cierra la pestaña o el navegador).
- Conéctate a Internet.
- El mensaje se envía en segundo plano.
Poder enviar en segundo plano de esta manera también genera una mejora percibida del rendimiento. La app no necesita hacer un gran esfuerzo para enviar el mensaje, por lo que puede agregarlo al resultado de inmediato.
Cómo solicitar una sincronización en segundo plano
En el verdadero estilo de la Web extensible, esta es una función de bajo nivel que te brinda la libertad de hacer lo que necesitas. Solicitas que se active un evento cuando el usuario tenga conectividad, lo que es inmediato si el usuario ya tiene conectividad. Luego, escuchas ese evento y haces lo que necesites.
Al igual que los mensajes push, usa un service worker como objetivo 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. En lo anterior, doSomeStuff()
debe mostrar una promesa que indique el éxito o el error de lo que intenta 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 anterior) debe ser único para una sincronización determinada. Si te registras para una sincronización con la misma etiqueta que una sincronización pendiente, esta se fusiona con la sincronización existente. Esto significa que puedes registrarte para una sincronización de "borrar carpeta de salida" cada vez que el usuario envíe un mensaje, pero si envía 5 mensajes sin conexión, solo recibirás una sincronización cuando esté en línea. Si deseas 5 eventos de sincronización independientes, usa etiquetas únicas.
Esta es una demostración simple que hace lo mínimo: usa el evento de sincronización para mostrar una notificación.
¿Para qué podría usar la sincronización en segundo plano?
Lo ideal es que lo uses para programar el envío de datos que te interesen 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… todo lo que quieras enviar al servidor, incluso si el usuario sale de la página o cierra la pestaña. La página podría almacenarlos en un almacén de "bandeja de salida" en IndexedDB, y el service worker los recuperaría y enviaría.
Sin embargo, también puedes usarlo para recuperar pequeños fragmentos de datos…
¡Otra demostración!
Esta es la demostración de Wikipedia sin conexión que creé para Acelerar la carga de páginas. Desde entonces, le agregué un poco de magia de sincronización en segundo plano.
Pruébalo por tu cuenta. Asegúrate de usar Chrome 49 o versiones posteriores y, luego, haz lo siguiente:
- Ve a cualquier artículo, por ejemplo, Chrome.
- Desconecta el dispositivo (ya sea con el modo de avión o con un proveedor de servicios móviles terrible como el mío).
- Haz clic en un vínculo a otro artículo.
- Se te informará que no se pudo cargar la página (también aparecerá si la página tarda un poco en cargarse).
- Aceptar las notificaciones
- Cierra el navegador.
- Conectarse
- Recibirás una notificación cuando el artículo se descargue, se almacenen en caché y esté listo para ver.
Con este patrón, el usuario puede guardar el teléfono en el bolsillo y seguir con su vida, sabiendo que el teléfono le alertará cuando recupere lo que buscaba.
Permisos
Las demostraciones que mostré usan notificaciones web, que requieren permiso, pero la sincronización en segundo plano no.
Los eventos de sincronización suelen completarse mientras el usuario tiene una página abierta en el sitio, por lo que solicitar su permiso sería una experiencia negativa. En su lugar, 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 del evento tiene un límite, por lo que no puedes usarlos para hacer ping a un servidor cada x segundos, minar bitcoins ni hacer lo que sea.
Por supuesto, estas restricciones pueden relajarse o endurecerse según el uso real.
Mejora progresiva
Pasará un tiempo hasta que todos los navegadores admitan la sincronización en segundo plano, en especial porque Safari y Edge aún no admiten los service workers. Pero la mejora progresiva ayuda en este caso:
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 el usuario parece tener una 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 en segundo plano periódica, puedes solicitar un evento restringido por intervalo de tiempo, estado de la batería y estado de la red. Por supuesto, esto requeriría el permiso del usuario, y también dependerá del navegador cuándo y con qué frecuencia se activen estos eventos. En otras palabras, un sitio de noticias podría solicitar la sincronización cada hora, pero el navegador podría saber que solo lo lees a las 7:00 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, llevamos patrones exitosos de Android y iOS a la Web, sin dejar de lado lo que la hace genial.