Sincronizzazione in background

Jake Archibald
Jake Archibald

Sincronizzazione in background è una nuova API web che consente di posticipare le azioni finché l'utente non ha una connettività stabile. In questo modo, tutto ciò che l'utente vuole inviare viene effettivamente inviato.

Il problema

Internet è un ottimo posto per perdere tempo. Senza perdere tempo su internet, non sapremmo che ai gatti non piacciono i fiori, ai camaleonti amano le bolle o che il nostro Eric Bidelman è un eroe del putt del putt di fine anni'90.

ma a volte non vogliamo perdere tempo. L'esperienza utente desiderata è più simile alla seguente:

  1. Il telefono dalla tasca.
  2. Raggiungi un obiettivo minore.
  3. Il telefono è riportato in tasca.
  4. Ripristina tutto.

Purtroppo questa esperienza è spesso interrotta da una scarsa connettività. Ci siamo passati tutti. Stai fissando uno schermo bianco o una ruota che gira e sai che devi arrenderti e andare avanti con la tua vita, ma aspetta ancora 10 secondi per maggiore sicurezza. Dopo quei 10 secondi? Niente.

Ma perché arrendersi ora? Hai già investito tempo, quindi allontanarti senza nulla sarebbe uno spreco, quindi continui ad aspettare. A questo punto vuoi rinunciare, ma sai che il secondo è il secondo prima che tutto si sarebbe caricato se solo tu avessi aspettato.

I service worker risolvono la parte relativa al caricamento della pagina consentendo di pubblicare i contenuti da una cache. E quando la pagina deve inviare qualcosa al server?

Al momento, se l'utente preme "Invia" su un messaggio, deve guardare l'icona di rotazione finché il messaggio non viene completato. Se tentano di uscire o di chiudere la scheda, usiamo onbeforeunload per visualizzare un messaggio del tipo "No, devo fissare ancora un po' la rotellina. Scusa". Se l'utente non ha una connessione, viene avvisato "Spiacenti, devi tornare più tardi e riprovare".

Questa è una spazzatura. La sincronizzazione in background ti consente di fare meglio.

Soluzione

Il seguente video mostra Emojoy, una demo solo per chat in chat con emoji. Si tratta di un'app web progressiva che funziona offline-first. L'app utilizza notifiche e messaggi push e la sincronizzazione in background.

Se l'utente prova a inviare un messaggio quando la connessione non è disponibile, per fortuna il messaggio viene inviato in background una volta ottenuta la connettività.

Da marzo 2016, la sincronizzazione in background è disponibile in Chrome dalla versione 49 e successive. Per controllare l'azione:

  1. Apri Emojoy.
  2. Vai offline (utilizzando la modalità aereo o recati nella tua gabbia Faraday di zona).
  3. Digita un messaggio.
  4. Torna alla schermata Home (facoltativamente chiudi la scheda o il browser).
  5. Vai online.
  6. Il messaggio viene inviato in background.

La possibilità di inviare messaggi in background come questo comporta anche un miglioramento del rendimento percepito. L'app non deve fare tante cose per l'invio del messaggio, quindi può aggiungerlo subito all'output.

Come richiedere una sincronizzazione in background

Nel vero stile Web estendibile, questa è una funzionalità di basso livello che ti offre la libertà di fare ciò che ti serve. Chiedi che un evento venga attivato quando l'utente è connesso, ovvero immediatamente se l'utente ha già questa connessione. Quindi, ascolti l'evento e fai tutto ciò che ti serve.

Come i messaggi push, utilizza un service worker come target dell'evento, che ne consente il funzionamento anche quando la pagina non è aperta. Per iniziare, registrati per la sincronizzazione da una pagina:

// 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());
  }
});

e il gioco è fatto. In precedenza, doSomeStuff() deve restituire una promessa che indica l'esito positivo o negativo di qualsiasi operazione che sta tentando di eseguire. Se viene completato, la sincronizzazione è completa. Se l'operazione non va a buon fine, verrà programmato un nuovo tentativo di sincronizzazione. Anche i tentativi di sincronizzazione attendono la connettività e utilizzano un backoff esponenziale.

Il nome del tag della sincronizzazione ("myFirstSync" nell'esempio riportato sopra) deve essere univoco per una determinata sincronizzazione. Se ti registri per una sincronizzazione utilizzando lo stesso tag di una sincronizzazione in attesa, il tag si unisce alla sincronizzazione esistente. Ciò significa che puoi registrarti per una sincronizzazione di "cancellazione della posta in uscita" ogni volta che l'utente invia un messaggio, ma se invia 5 messaggi mentre è offline, riceverai una sola sincronizzazione quando sarà online. Se desideri cinque eventi di sincronizzazione separati, utilizza tag univoci.

Ecco una demo semplice che utilizza l'evento di sincronizzazione per mostrare una notifica.

Per che cosa posso utilizzare la sincronizzazione in background?

Idealmente, dovresti utilizzarlo per pianificare l'invio dei dati che ti interessano al di là del ciclo di vita della pagina. Messaggi di chat, email, aggiornamenti di documenti, modifiche alle impostazioni, caricamenti di foto... tutto ciò che desideri raggiungere il server anche se l'utente esce dalla scheda o chiude la scheda. La pagina potrebbe archiviarli in un archivio "in uscita" in indexDB e il service worker li recupera e li invia.

Tuttavia, puoi utilizzarlo anche per recuperare piccoli bit di dati...

Un'altra demo!

Questa è la demo di Wikipedia offline che ho creato per incrementare il carico della pagina. Da allora ho aggiunto una magia di sincronizzazione dello sfondo.

Prova anche tu. Assicurati di utilizzare Chrome 49 o versioni successive, quindi:

  1. Apri un qualsiasi articolo, ad esempio Chrome.
  2. Vai offline (utilizzando la modalità aereo o unisciti a un operatore di telefonia mobile pessimo come il mio).
  3. Fai clic su un link a un altro articolo.
  4. Dovresti ricevere un messaggio che indica che il caricamento della pagina non è riuscito (viene visualizzato anche se il caricamento della pagina richiede più tempo).
  5. Accetta le notifiche.
  6. Chiudi il browser.
  7. Vai online
  8. Riceverai una notifica quando l'articolo viene scaricato, memorizzato nella cache e pronto per essere visualizzato.

Grazie a questa sequenza, l'utente può mettere lo smartphone in tasca e occuparsi della sua vita, sapendo che lo smartphone li avvisa quando viene recuperato il dispositivo che desidera.

Autorizzazioni

Le demo che ho mostrato utilizzano notifiche web, che richiedono l'autorizzazione, ma non la sincronizzazione in background.

Gli eventi di sincronizzazione spesso vengono completati mentre l'utente ha una pagina aperta sul sito, pertanto richiedere l'autorizzazione dell'utente non sarebbe un'esperienza soddisfacente. Per evitare utilizzi illeciti, limitiamo invece i casi in cui è possibile registrare e attivare le sincronizzazioni. Ad esempio:

  • Puoi registrarti a un evento di sincronizzazione solo quando l'utente ha una finestra aperta sul sito.
  • Il tempo di esecuzione dell'evento è limitato, quindi non puoi utilizzarli per inviare un ping a un server ogni x secondi, estrarre bitcoin o altro.

Naturalmente, queste limitazioni potrebbero allentarsi o essere più stringenti in base all'uso reale.

Miglioramento progressivo

Ci vorrà un po' di tempo prima che tutti i browser supportino la sincronizzazione in background, soprattutto perché Safari ed Edge non supportano ancora i service worker. Tuttavia, il miglioramento progressivo è utile in questo 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();
}

Se i Service worker o la sincronizzazione in background non sono disponibili, pubblica semplicemente i contenuti dalla pagina, come faresti normalmente.

È consigliabile utilizzare la sincronizzazione in background anche se l'utente sembra avere una buona connettività, poiché ti protegge dalle navigazioni e dalle chiusure di schede durante l'invio dei dati.

Il futuro

Il nostro obiettivo è distribuire la sincronizzazione in background a una versione stabile di Chrome nella prima metà del 2016, lavorando su una variante, la "sincronizzazione periodica in background". Con la sincronizzazione in background periodica, puoi richiedere un evento limitato in base all'intervallo di tempo, allo stato della batteria e allo stato della rete. Ciò richiederebbe l'autorizzazione dell'utente, ovviamente, e spetta al browser stabilire quando e con quale frequenza vengono attivati questi eventi. In altre parole, un sito di notizie potrebbe richiedere la sincronizzazione ogni ora, ma il browser potrebbe sapere che leggi quel sito soltanto alle 07:00, quindi la sincronizzazione verrebbe attivata ogni giorno alle 06:50. Questa idea è un po' diversa da quella della sincronizzazione una tantum, ma sta arrivando.

A poco a poco, stiamo introducendo modelli di successo da Android e iOS sul Web, pur conservando ciò che rende grande il web.