Przedstawiamy synchronizację w tle

Jake Archibald
Jake Archibald

Data publikacji: 8 grudnia 2015 r.

Synchronizacja w tle to interfejs Web API, który umożliwia odłożenie działań do momentu, gdy użytkownik będzie mieć stabilne połączenie. Dzięki temu możesz pomagać użytkownikom w wysyłaniu dowolnych plików, gdy tylko będzie to możliwe.

Browser Support

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

Source

Problem

Internet to świetne miejsce na marnowanie czasu. Gdybyśmy nie spędzali czasu w internecie, nie wiedzielibyśmy, że koty nie lubią kwiatów, kameleony uwielbiają bańki ani że Eric Bidelman był bohaterem minigolfa z końcówki lat 90.

Ale czasami, tylko czasami, nie chcemy tracić czasu. Idealne wrażenia użytkownika to:

  1. Telefon wyjęty z kieszeni.
  2. Osiągnij mniejszy cel.
  3. Telefon z powrotem w kieszeni.
  4. Wznów życie.

Niestety często jest to utrudnione przez słabe połączenie. Wszyscy to znamy. Patrzysz na biały ekran lub spinner i wiesz, że powinnaś(-eś) odpuścić i zająć się czymś innym, ale na wszelki wypadek czekasz jeszcze 10 sekund. Po tych 10 sekundach? Nic.

Ale dlaczego teraz się poddawać? Poświęciłeś(-aś) już na to czas, więc odejście z niczym byłoby stratą. Dlatego czekasz dalej. W tym momencie chcesz się poddać, ale wiesz, że gdy to zrobisz, wszystko załaduje się w następnej sekundzie, gdybyś tylko poczekał.

Skrypty service worker rozwiązują problem z ładowaniem strony, umożliwiając wyświetlanie treści z pamięci podręcznej. A co w sytuacji, gdy strona musi coś wysłać na serwer?

Obecnie, gdy użytkownik kliknie „Wyślij”, musi czekać, aż pojawi się spinner. Jeśli użytkownik spróbuje przejść do innej karty lub ją zamknąć, użyjemy funkcji onbeforeunload, aby wyświetlić komunikat w stylu „Nie, musisz jeszcze trochę popatrzeć na ten spinner. Przepraszam”. Jeśli użytkownik nie ma połączenia, wyświetlamy komunikat „Przepraszamy, musisz wrócić później i spróbować ponownie”.

Synchronizacja w tle pozwala Ci działać skuteczniej.

Rozwiązanie

Poniższy film przedstawia Emojoy, czyli demonstrację czatu opartego wyłącznie na emotikonach. Jest to progresywna aplikacja internetowa, która działa przede wszystkim w trybie offline. Aplikacja korzysta z wiadomości i powiadomień push oraz synchronizacji w tle.

Jeśli użytkownik spróbuje wysłać wiadomość, gdy nie ma połączenia z internetem, zostanie ona wysłana w tle po uzyskaniu połączenia.

Możliwość wysyłania w tle w ten sposób poprawia też postrzeganą wydajność. Aplikacja nie musi tak bardzo przejmować się wysyłaniem wiadomości, więc może od razu dodać ją do danych wyjściowych.

Synchronizacja w tle jest dostępna od Chrome 49.

Jak poprosić o synchronizację w tle

Zgodnie z zasadami rozszerzalnej sieci jest to funkcja niskiego poziomu, która daje Ci swobodę działania. Prosisz o wywołanie zdarzenia, gdy użytkownik ma połączenie z internetem. Jeśli użytkownik ma już połączenie, nastąpi to natychmiast. Następnie nasłuchujesz tego zdarzenia i wykonujesz potrzebne czynności.

Podobnie jak w przypadku wiadomości push, jako celu zdarzenia używa skryptu service worker, dzięki czemu działa, gdy strona nie jest otwarta. Aby rozpocząć, zarejestruj synchronizację ze strony:

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

To wszystko. doSomeStuff() powinna zwracać obietnicę wskazującą na powodzenie lub niepowodzenie wykonywanej operacji. Jeśli obietnica zostanie spełniona, synchronizacja zostanie zakończona. Jeśli się nie uda, zaplanujemy kolejną próbę synchronizacji. Ponowne próby synchronizacji również czekają na połączenie i wykorzystują wzrastający czas do ponowienia.

Nazwa tagu synchronizacji („myFirstSync” w przykładzie) powinna być unikalna w przypadku danej synchronizacji. Jeśli zarejestrujesz synchronizację za pomocą tego samego tagu co oczekująca synchronizacja, zostanie ona połączona z istniejącą synchronizacją. Oznacza to, że możesz zarejestrować synchronizację „wyczyść skrzynkę nadawczą” za każdym razem, gdy użytkownik wyśle wiadomość, ale jeśli wyśle 5 wiadomości w trybie offline, po przejściu do trybu online otrzymasz tylko jedną synchronizację. Aby uzyskać 5 oddzielnych zdarzeń synchronizacji, użyj unikalnych tagów.

Oto wersja demonstracyjna, która używa zdarzenia synchronizacji do wyświetlania powiadomienia.

Zastosowania synchronizacji w tle

Najlepiej używać go do planowania wysyłania danych, które są ważne po zakończeniu działania strony. wiadomości na czacie, e-maile, aktualizacje dokumentów, zmiany ustawień, przesyłanie zdjęć lub inne treści, które chcesz przesłać na serwer, nawet jeśli użytkownik opuści stronę lub zamknie kartę. Strona może przechowywać te dane w „skrzynce nadawczej” w indexedDB, a skrypt service worker będzie je pobierać i wysyłać.

Możesz go jednak używać do pobierania niewielkich ilości danych.

Demo Wikipedii offline

To jest wersja demonstracyjna Wikipedii offline, którą utworzyłem na potrzeby artykułu Supercharging Page Load. Dodałem do niej trochę magii synchronizacji w tle.

Wypróbuj to:

  1. Pozostaw tę kartę przeglądarki otwartą.
  2. Przejdź w tryb offline, włączając tryb samolotowy lub wyłączając Wi-Fi.
  3. Kliknij link do innego artykułu.
  4. Powinien pojawić się komunikat o tym, że nie udało się wczytać strony (pojawi się on również, jeśli wczytywanie strony trwa dłużej).
  5. Zgódź się na powiadomienia.
  6. Zamknij przeglądarkę.
  7. Włącz tryb online
  8. Gdy artykuł zostanie pobrany, zapisany w pamięci podręcznej i będzie gotowy do wyświetlenia, otrzymasz powiadomienie.

Dzięki temu użytkownik może włożyć telefon do kieszeni i zająć się swoimi sprawami, wiedząc, że telefon powiadomi go, gdy znajdzie to, czego szukał.

Uprawnienia

W pokazanych przeze mnie wersjach demonstracyjnych użyto powiadomień internetowych, które wymagają uprawnień, ale sama synchronizacja w tle nie.

Zdarzenia synchronizacji często są wykonywane, gdy użytkownik ma otwartą stronę witryny, więc wymaganie od niego zgody pogorszyłoby komfort korzystania z usługi. Aby zapobiec nadużyciom, ograniczamy możliwość rejestrowania i wywoływania synchronizacji. Na przykład:

  • Możesz zarejestrować się na zdarzenie synchronizacji tylko wtedy, gdy użytkownik ma otwarte okno witryny.
  • Czas wykonania zdarzenia jest ograniczony, więc nie możesz go używać do pingowania serwera co x sekund, wydobywania bitcoinów itp.

Oczywiście te ograniczenia mogą być mniej lub bardziej rygorystyczne w zależności od rzeczywistego wykorzystania.

Stopniowe ulepszanie

Zanim synchronizacja w tle stanie się standardem, możesz używać jej jako ulepszenia progresywnego:

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

Jeśli mechanizmy Service Worker lub synchronizacja w tle nie są dostępne, opublikuj treść ze strony tak jak dotychczas.

Warto używać synchronizacji w tle nawet wtedy, gdy użytkownik ma dobre połączenie, ponieważ chroni to przed nawigacją i zamykaniem kart podczas wysyłania danych.

Przyszłość

Planujemy wprowadzić synchronizację w tle w stabilnej wersji Chrome w pierwszej połowie 2016 roku. Pracujemy też nad wariantem „okresowa synchronizacja w tle”. Dzięki okresowej synchronizacji w tle możesz poprosić o zdarzenie ograniczone przez przedział czasu, stan baterii i stan sieci. Wymaga to oczywiście zgody użytkownika, a także zależy od przeglądarki, kiedy i jak często te zdarzenia są wywoływane. Innymi słowy, witryna z wiadomościami może wysyłać prośbę o synchronizację co godzinę, ale przeglądarka może wiedzieć, że czytasz tę witrynę tylko o 7:00, więc synchronizacja będzie się odbywać codziennie o 6:50. Ten pomysł jest nieco bardziej odległy niż jednorazowa synchronizacja, ale wkrótce go wprowadzimy.

Stopniowo przenosimy do internetu sprawdzone wzorce z Androida i iOS, zachowując przy tym to, co sprawia, że internet jest tak atrakcyjny.