W 2015 r. wprowadziliśmy synchronizację w tle, która umożliwia skrypt service worker w celu odroczenia pracy do momentu uzyskania połączenia przez użytkownika. Oznacza to, że użytkownik może wpisać wiadomość, naciśnij przycisk Wyślij i opuść witrynę, wiedząc, że wiadomość zostanie wysłana teraz lub gdy mają łączność.
Jest to przydatna funkcja, ale wymaga, aby skrypt service worker był aktywny pobrać. Nie stanowi to problemu w przypadku krótkich zadań, takich jak wysyłanie wiadomości, jeśli przeglądarka wyłączy skrypt service worker, ponieważ może to zagrażać prywatności użytkownika baterii.
Co więc w sytuacji, gdy musisz pobrać coś, co zajmuje dużo czasu, np. film, podcast poziomów gry. Właśnie do tego służy pobieranie w tle.
Pobieranie w tle jest dostępne domyślnie od Chrome 74.
Oto krótka, dwuminutowa prezentacja, która pokazuje, jak tradycyjne funkcje działają w odróżnieniu od pobierania w tle:
Wypróbuj wersję demonstracyjną i przejrzyj kod.
Jak to działa
Proces pobierania w tle działa w następujący sposób:
- Mówisz przeglądarce, aby wykonywała w tle grupę pobierania.
- Przeglądarka pobiera te dane, a następnie wyświetla użytkownikowi postęp.
- Gdy pobieranie się zakończy lub się nie uda, przeglądarka otworzy skrypt service worker i uruchomi zdarzenie. i opowie, co się stało. Na tym etapie możesz zdecydować, co zrobić z odpowiedziami.
Jeśli po wykonaniu kroku 1 użytkownik zamknie strony w Twojej witrynie, pobieranie będzie kontynuowane. Ponieważ pobieranie jest bardzo widoczne i można łatwo je przerwać, nie ma obawy o prywatność, synchronizacji w tle. Skrypt service worker nie jest stale uruchomiony, więc nie jest to problem. że może nadużywać systemu, np. wydobywać bitcoiny w tle.
Na niektórych platformach (takich jak Android) przeglądarka może się zamknąć po kroku 1, ponieważ przeglądarka może przekazać pobieranie do systemu operacyjnego.
Jeśli użytkownik rozpocznie pobieranie, będąc offline, lub przejdzie w tryb offline podczas pobierania, działanie w tle pobieranie zostanie wstrzymane i wznowione później.
Interfejs API
Wykrywanie cech
Tak jak w przypadku każdej nowej funkcji, musisz sprawdzić, czy przeglądarka ją obsługuje. W przypadku pobierania w tle tak proste, jak:
if ('BackgroundFetchManager' in self) {
// This browser supports Background Fetch!
}
Rozpoczynanie pobierania w tle
Główny interfejs API zawiesza się z rejestracją skryptu service worker, dlatego najpierw musisz zarejestrować skrypt service worker. Następnie:
navigator.serviceWorker.ready.then(async (swReg) => {
const bgFetch = await swReg.backgroundFetch.fetch('my-fetch', ['/ep-5.mp3', 'ep-5-artwork.jpg'], {
title: 'Episode 5: Interesting things.',
icons: [{
sizes: '300x300',
src: '/ep-5-icon.png',
type: 'image/png',
}],
downloadTotal: 60 * 1024 * 1024,
});
});
Funkcja backgroundFetch.fetch
przyjmuje 3 argumenty:
Parametry | |
---|---|
id |
string jednoznacznie identyfikuje to pobranie w tle.
|
requests |
Array<Request|string>
Rzeczy do pobrania. Ciągi znaków będą traktowane jako adresy URL i przekształcane w Request za pośrednictwem: new Request(theString) .
Możesz pobierać elementy z innych źródeł, o ile pozwalają na to zasoby CORS. Uwaga: Chrome obecnie nie obsługuje żądań, które: wymagają procesu wstępnego CORS. |
options |
Obiekt, który może zawierać: |
options.title |
string Tytuł, który wyświetla się w przeglądarce wraz z postępem. |
options.icons |
Array<IconDefinition> Tablica obiektów z „src”, „size” i „typem”. |
options.downloadTotal |
number Całkowity rozmiar treści odpowiedzi (po rozpakowaniu gzip). Chociaż jest to opcjonalne, zdecydowanie zalecamy jego podanie. Pozwala określić, rozmiar pliku do pobrania i informacje o postępach. Jeśli nie podasz przeglądarki poinformuje użytkownika, że rozmiar jest nieznany, i w rezultacie użytkownik może może przerwać pobieranie. Jeśli pobieranie w tle przekroczy podaną tutaj liczbę, pobieranie zostanie przerwane. Jest
Nie ma sprawy, jeśli rozmiar pobieranego pliku jest mniejszy niż |
Funkcja backgroundFetch.fetch
zwraca obietnicę, która zwraca wartość BackgroundFetchRegistration
. tak
szczegóły omówimy później. Obietnica zostanie odrzucona, jeśli użytkownik zrezygnował z pobierania plików.
podanych parametrów jest nieprawidłowe.
Udostępnianie wielu żądań na jedno pobieranie w tle pozwala łączyć elementy, które są logicznie z perspektywy użytkownika. Na przykład film może zostać podzielony na tysiące zasobów (zwykle przy MPEG-DASH), i dostarczać dodatkowe zasoby, np. obrazy. Poziom gry może być rozłożony na wielu zasobów JavaScript, obrazów i dźwięku. Dla użytkownika to jest tylko „film” lub „poziom”.
Uzyskiwanie istniejącego pobierania w tle
Dotychczasowe pobieranie w tle można pobrać w ten sposób:
navigator.serviceWorker.ready.then(async (swReg) => {
const bgFetch = await swReg.backgroundFetch.get('my-fetch');
});
...przekazując id żądanego pobierania w tle. get
zwraca wartość undefined
, jeśli nie ma podanej wartości
jest aktywne pobieranie w tle z tym identyfikatorem.
Pobieranie w tle jest uznawane za „aktywne” od momentu jego rejestracji aż do momentu, gdy się powiedzie, nie powiedzie się lub zostanie przerwane.
Listę wszystkich aktywnych pobrań w tle możesz wyświetlić za pomocą parametru getIds
:
navigator.serviceWorker.ready.then(async (swReg) => {
const ids = await swReg.backgroundFetch.getIds();
});
Rejestracje pobierania w tle
Pole BackgroundFetchRegistration
(bgFetch
w powyższych przykładach) ma następujące właściwości:
Właściwości | |
---|---|
id |
string Identyfikator pobierania w tle. |
uploadTotal |
number Liczba bajtów, które mają zostać wysłane do serwera. |
uploaded |
number Liczba bajtów, które zostały wysłane. |
downloadTotal |
number Wartość podana podczas rejestrowania pobierania w tle lub zero. |
downloaded |
number Liczba bajtów, które zostały odebrane. Ta wartość może się zmniejszyć. Jeśli na przykład połączenie zostanie przerwane i nie będzie można pobrać — w takim przypadku przeglądarka rozpoczyna pobieranie tego zasobu od początku. |
result |
Jedna z tych wartości:
|
failureReason |
Jedna z tych wartości:
|
recordsAvailable |
boolean Czy można uzyskać dostęp do powiązanych żądań/odpowiedzi? Gdy ma wartość Fałsz, nie można używać |
Metody | |
abort() |
Zwraca Promise<boolean> Przerywanie pobierania w tle. Zwrócona obietnica kończy się z wartością „true”, jeśli pobieranie zostało przerwane. |
matchAll(request, opts) |
Zwraca Promise<Array<BackgroundFetchRecord>> Pobierz żądania i udzielania odpowiedzi. Argumenty podane tutaj są takie same jak pamięć podręczna API. Wywołanie bez argumentów zwraca obietnicę dla wszystkich rekordów. Więcej informacji znajdziesz poniżej. |
match(request, opts) |
Zwraca wartość Promise<BackgroundFetchRecord> Tak jak wyżej, ale kończy się wartością w pierwszej kolejności. |
Wydarzenia | |
progress |
Uruchamiane, gdy dowolna z tych wartości: uploaded , downloaded , result lub
failureReason zmiana. |
Śledzenie postępów
Możesz to zrobić za pomocą zdarzenia progress
. Pamiętaj, że downloadTotal
jest wartością bez względu na to,
lub 0
, jeśli nie podano wartości.
bgFetch.addEventListener('progress', () => {
// If we didn't provide a total, we can't provide a %.
if (!bgFetch.downloadTotal) return;
const percent = Math.round(bgFetch.downloaded / bgFetch.downloadTotal * 100);
console.log(`Download progress: ${percent}%`);
});
Uzyskiwanie żądań i odpowiedzi
bgFetch.match('/ep-5.mp3').then(async (record) => {
if (!record) {
console.log('No record found');
return;
}
console.log(`Here's the request`, record.request);
const response = await record.responseReady;
console.log(`And here's the response`, response);
});
record
to BackgroundFetchRecord
i wygląda tak:
Właściwości | |
---|---|
request |
Request przesłane żądanie, |
responseReady |
Promise<Response> Pobrana odpowiedź. Odpowiedź kryje się za obietnicą, ponieważ być może jeszcze jej nie otrzymano. Obietnica zostanie odrzucony, jeśli nie uda się pobrać. |
Zdarzenia Service Worker
Wydarzenia | |
---|---|
backgroundfetchsuccess |
Udało się pobrać wszystko. |
backgroundfetchfailure |
Nie udało się pobrać co najmniej jednego pliku. |
backgroundfetchabort |
Nie udało się pobrać co najmniej jednego pliku.
Jest to przydatne tylko wtedy, gdy chcesz usunąć powiązane dane. |
backgroundfetchclick |
Użytkownik kliknął interfejs postępu pobierania. |
Obiekty zdarzeń mają następujące elementy:
Właściwości | |
---|---|
registration |
BackgroundFetchRegistration |
Metody | |
updateUI({ title, icons }) |
Umożliwia zmianę początkowo ustawionych tytułów lub ikon. Jest to opcjonalne, ale pozwala
podaj w razie potrzeby więcej kontekstu. Możesz to zrobić tylko *raz* w trakcie
Zdarzenia: backgroundfetchsuccess i backgroundfetchfailure . |
Reagowanie na sukces/niepowodzenie
Widzimy już zdarzenie progress
, ale przydaje się ono tylko wtedy, gdy użytkownik ma otwartą stronę
w Twojej witrynie. Główną zaletą pobierania w tle jest to, że wszystko działa, gdy użytkownik opuści
a nawet zamyka przeglądarkę.
Jeśli pobieranie w tle się zakończy, skrypt service worker otrzyma
zdarzenie backgroundfetchsuccess
, a event.registration
będzie rejestracją pobierania w tle.
Po tym zdarzeniu pobrane żądania i odpowiedzi przestaną być dostępne, więc jeśli chcesz je zachować, przenieś w podobny sposób do interfejsu API typucache.
Podobnie jak w przypadku większości zdarzeń skryptu service worker, użyj zasady event.waitUntil
, aby mechanizm ten wie, kiedy zdarzenie
zakończono.
Na przykład w mechanizmie Service Worker:
addEventListener('backgroundfetchsuccess', (event) => {
const bgFetch = event.registration;
event.waitUntil(async function() {
// Create/open a cache.
const cache = await caches.open('downloads');
// Get all the records.
const records = await bgFetch.matchAll();
// Copy each request/response across.
const promises = records.map(async (record) => {
const response = await record.responseReady;
await cache.put(record.request, response);
});
// Wait for the copying to complete.
await Promise.all(promises);
// Update the progress notification.
event.updateUI({ title: 'Episode 5 ready to listen!' });
}());
});
Błędy mogły sprowadzić się do pojedynczego błędu 404, który może nie być dla Ciebie ważny, nadal warto skopiować niektóre odpowiedzi do pamięci podręcznej w sposób opisany powyżej.
Reakcja na kliknięcie
Interfejs, w którym widać postęp pobierania i wynik, można kliknąć. Wydarzenie backgroundfetchclick
w:
umożliwia zareagowanie na ten proces. Tak jak powyżej, tłem będzie event.registration
pobierz rejestrację.
Zazwyczaj w przypadku tego zdarzenia należy otworzyć okno:
addEventListener('backgroundfetchclick', (event) => {
const bgFetch = event.registration;
if (bgFetch.result === 'success') {
clients.openWindow('/latest-podcasts');
} else {
clients.openWindow('/download-progress');
}
});
Dodatkowe materiały
Poprawka: w poprzedniej wersji tego artykułu pobieranie w tle było błędnie określane jako „standard internetowy”. Interfejs API nie spełnia obecnie standardów. Specyfikację można znaleźć w WICG jako wersję roboczą raportu dotyczącego grupy społeczności.