Sincronizzazione in background

Jake Archibald
Jake Archibald

Data di pubblicazione: 8 dicembre 2015

Sincronizzazione in background è un'API web che ti consente di posticipare le azioni finché l'utente non ha una connettività stabile. In questo modo puoi aiutare gli utenti a inviare i file che vogliono, non appena è possibile.

Browser Support

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

Source

Il problema

Internet è un ottimo posto per perdere tempo. Senza perdere tempo su internet, non sapremmo che i gatti non amano i fiori, che i camaleonti adorano le bolle o che Eric Bidelman è un eroe del minigolf della fine degli anni'90.

Ma a volte, solo a volte, non vogliamo perdere tempo. L'esperienza utente ideale è più simile a questa:

  1. Lo smartphone è fuori dalla tasca.
  2. Raggiungere un obiettivo secondario.
  3. Lo smartphone è di nuovo in tasca.
  4. Riprendi la vita.

Purtroppo, questa esperienza viene spesso interrotta da una connettività scadente. Può capitare. Stai fissando una schermata bianca o un cursore di caricamento e sai che dovresti arrenderti e andare avanti con la tua vita, ma aspetti altri 10 secondi per sicurezza. Dopo 10 secondi? Niente.

Ma perché arrendersi ora? Hai già investito del tempo, quindi andartene senza niente sarebbe uno spreco, perciò continui ad aspettare. A questo punto vorresti arrenderti, ma sai che nel momento in cui lo fai, è il momento prima che tutto si carichi se solo avessi aspettato.

I service worker risolvono il problema del caricamento delle pagine consentendoti di pubblicare contenuti da una cache. Ma cosa succede quando la pagina deve inviare qualcosa al server?

Al momento, se l'utente preme "Invia" per un messaggio, deve fissare un indicatore di caricamento fino al completamento dell'operazione. Se l'utente tenta di uscire o chiudere la scheda, utilizziamo onbeforeunload per visualizzare un messaggio del tipo "No, devi guardare ancora un po' questo indicatore di caricamento. Scusa". Se l'utente non ha una connessione, gli diciamo "Ci dispiace, devi tornare più tardi e riprovare".

La sincronizzazione in background ti consente di fare di meglio.

Soluzione

Il seguente video mostra Emojoy, una demo di chat solo con emoji. È un'app web progressiva e funziona prima di tutto offline. L'app utilizza messaggi push e notifiche e la sincronizzazione in background.

Se l'utente tenta di inviare un messaggio quando la connettività è pari a zero, il messaggio viene inviato in background una volta ripristinata la connettività.

La possibilità di inviare in background in questo modo comporta anche un miglioramento percepito delle prestazioni. L'app non deve fare un gran problema dell'invio del messaggio, quindi può aggiungerlo direttamente all'output.

La sincronizzazione in background è disponibile a partire da Chrome 49.

Come richiedere una sincronizzazione in background

In vero stile web estensibile, questa è una funzionalità di basso livello che ti dà la libertà di fare ciò che ti serve. Chiedi che venga attivato un evento quando l'utente ha connettività, il che avviene immediatamente se l'utente ha già connettività. Poi, ascolta l'evento e fai quello che devi fare.

Come i messaggi push, utilizza un service worker come target dell'evento, il che gli consente di funzionare quando la pagina non è aperta. Per iniziare, registrati per una 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());
  }
});

È tutto. doSomeStuff() deve restituire una promessa che indica l'esito positivo o negativo dell'operazione che sta tentando di eseguire. Se la promessa viene soddisfatta, la sincronizzazione è completata. Se non va a buon fine, viene pianificata un'altra sincronizzazione. I nuovi tentativi di sincronizzazione attendono anche la connettività e utilizzano un backoff esponenziale.

Il nome del tag della sincronizzazione ("myFirstSync" nell'esempio) deve essere univoco per una determinata sincronizzazione. Se registri una sincronizzazione utilizzando lo stesso tag di una sincronizzazione in attesa, questa viene unita a quella esistente. Ciò significa che puoi registrarti per una sincronizzazione "clear-outbox" ogni volta che l'utente invia un messaggio, ma se invia 5 messaggi offline, riceverai una sola sincronizzazione quando torna online. Per ottenere 5 eventi di sincronizzazione separati, utilizza tag univoci.

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

Utilizzi della sincronizzazione in background

Idealmente, lo utilizzeresti per pianificare l'invio di tutti i dati che ti interessano oltre la durata della pagina. Messaggi di chat, email, aggiornamenti di documenti, modifiche delle impostazioni, caricamenti di foto o qualsiasi contenuto che vuoi raggiungere il server, anche se l'utente esce dalla pagina o chiude la scheda. La pagina potrebbe memorizzarli in un archivio "Posta in uscita" in IndexedDB e il service worker li recupererebbe e li invierebbe.

Tuttavia, puoi utilizzarlo anche per recuperare piccole quantità di dati.

Demo di Wikipedia offline

Questa è la demo di Wikipedia offline che ho creato per Supercharging Page Load. Da allora ho aggiunto un po' di magia alla sincronizzazione in background.

Prova anche tu:

  1. Tieni aperto il browser su questa scheda.
  2. Vai offline con la modalità aereo o disattivando il Wi-Fi.
  3. Fai clic su un link a un altro articolo.
  4. Dovresti ricevere un messaggio che ti informa che il caricamento della pagina non è riuscito (questo messaggio viene visualizzato anche se il caricamento della pagina richiede un po' di 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 la visualizzazione.

Utilizzando questo pattern, l'utente può mettere lo smartphone in tasca e continuare la sua vita, sapendo che lo smartphone lo avviserà quando avrà recuperato ciò che voleva.

Autorizzazioni

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

La sincronizzazione degli eventi viene spesso completata mentre l'utente ha una pagina aperta sul sito, quindi richiedere l'autorizzazione dell'utente sarebbe un'esperienza negativa. Al contrario, stiamo limitando i momenti in cui è possibile registrare e attivare le sincronizzazioni per evitare abusi. 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 eseguire il ping di un server ogni x secondi, estrarre bitcoin o altro.

Naturalmente, queste limitazioni possono essere allentate o inasprite in base all'utilizzo nel mondo reale.

Potenziamento progressivo

Mentre attendiamo che la sincronizzazione in background diventi la base, puoi utilizzarla come miglioramento progressivo:

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 i contenuti della pagina come faresti oggi.

Vale la pena utilizzare la sincronizzazione in background anche se l'utente sembra avere una buona connettività, in quanto protegge da navigazioni e chiusure di schede durante l'invio dei dati.

Futuro =

Prevediamo di rilasciare la sincronizzazione in background in una versione stabile di Chrome nella prima metà del 2016, mentre lavoriamo a una variante, la "sincronizzazione periodica in background". Con la sincronizzazione periodica in background, puoi richiedere un evento limitato da intervallo di tempo, stato della batteria e stato della rete. Naturalmente, ciò richiede l'autorizzazione dell'utente e spetta al browser decidere 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 solo alle 07:00, quindi la sincronizzazione verrà eseguita ogni giorno alle 06:50. Questa idea è un po' più lontana della sincronizzazione una tantum, ma arriverà.

Stiamo portando gradualmente sul web i pattern di successo di Android e iOS, mantenendo al contempo le caratteristiche che rendono il web un ambiente eccezionale.