2015 年に Google はバックグラウンド同期を導入し、 ユーザーが接続できるまで作業を延期します。つまり、ユーザーは メッセージを送ってから、[送信] を押し、メッセージが今すぐまたは 接続します。
これは便利な機能ですが、サービス期間中に Service Worker を 取得しますメッセージの送信のような短い作業では問題になりませんが、タスクに あまりに長くなると、ブラウザが Service Worker を強制終了します。そうしないと、ユーザーのプライバシーが損なわれ、 できます。
では、ダウンロードに時間がかかる映画、ポッドキャスト、 制限します。そのために、バックグラウンド フェッチを使用します。
バックグラウンド フェッチは、Chrome 74 以降でデフォルトで使用できます。
こちらは 2 分間の簡単なデモで、従来の状態とバックグラウンド フェッチを使用した場合を比較したものです。
仕組み
バックグラウンド取得は次のように動作します。
- 一連のフェッチをバックグラウンドで実行するようブラウザに指示します。
- ブラウザはこれらを取得して、進行状況をユーザーに表示します。
- 取得が完了または失敗すると、ブラウザは Service Worker を開き、イベントを発生させます。 何が起きたかを教えてくれます。ここで、回答の処理方法を決定します。
ステップ 1 の後にユーザーがサイトのページを閉じても問題ありません。ダウンロードは続行されます。なぜなら、 取得がはっきりと表示され、簡単に中止できる。長すぎるというプライバシーに関する懸念はない バックグラウンド同期タスクを実行しますService Worker は常に動作しているわけではないため、 バックグラウンドでビットコインのマイニングを行うなどして、システムを悪用する可能性があると判断しました。
一部のプラットフォーム(Android など)では、ステップ 1 の後でブラウザが閉じることがあります。これは、 ブラウザは取得をオペレーティング システムに引き渡せます。
ユーザーがオフライン中にダウンロードを開始したり、ダウンロード中にオフラインになった場合、バックグラウンド 取得は一時停止され、後で再開されます。
API
機能検出
他の新機能と同様に、ブラウザがこの機能をサポートしているかどうかを検出する必要があります。バックグラウンド フェッチについては、 次のようにシンプルにできます。
if ('BackgroundFetchManager' in self) {
// This browser supports Background Fetch!
}
バックグラウンド取得の開始
メイン API が Service Worker の登録を終了し、 必ず Service Worker を登録してください以下の手順を行います。
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,
});
});
backgroundFetch.fetch
は次の 3 つの引数を取ります。
パラメータ | |
---|---|
id |
string でこのバックグラウンド フェッチを一意に識別します。 ID が既存の背景と一致する場合、 |
requests |
Array<Request|string>
取得するアイテム。文字列は URL として扱われ、 new Request(theString) 経由の Request 。
リソースで許可されている限り、他のオリジンから取得できます。 CORS。 注: 現在のところ、Chrome は CORS プリフライトが必要です |
options |
以下を含むことができるオブジェクト。 |
options.title |
string 進行状況とともに表示されるブラウザのタイトル。 |
options.icons |
Array<IconDefinition> `src`、`size`、`type` を持つオブジェクトの配列。 |
options.downloadTotal |
number レスポンス本文の合計サイズ(gzip 圧縮解除後)。 これは省略可能ですが、指定することを強くおすすめします。データ アナリストは、 ダウンロードのサイズ、進行状況に関する情報などがあります。「新規顧客の獲得」目標を ブラウザはユーザーにサイズが不明であることを通知し、その結果、 ダウンロードを中止する可能性があります。 バックグラウンドでの取得によるダウンロード回数がここで指定した数を超えると、ダウンロードは中止されます。です。
ダウンロードが |
backgroundFetch.fetch
は、BackgroundFetchRegistration
で解決される Promise を返します。私は
後ほど詳しく説明します。ユーザーがダウンロードをオプトアウトしている場合、またはいずれか 1 つの場合、Promise は拒否されます。
無効なパラメータです。
1 回のバックグラウンド フェッチで多数のリクエストを提供することで、論理的には ユーザーに提示しますたとえば、映画が数千個のリソース(通常、 MPEG-DASH), 画像などの追加リソースが付属していますあるゲームのレベルは、 JavaScript、画像、音声の各リソース。ユーザーにとっては「映画」または「レベル」だけです。
既存のバックグラウンド取得を取得する
既存のバックグラウンド取得は次のように取得できます。
navigator.serviceWorker.ready.then(async (swReg) => {
const bgFetch = await swReg.backgroundFetch.get('my-fetch');
});
必要なバックグラウンド フェッチの id を渡します。見つからない場合、get
は undefined
を返します。
バックグラウンド取得がアクティブになります
バックグラウンド フェッチは「アクティブ」と見なされる登録から成功するまで 失敗するか中止されます
getIds
を使用すると、すべてのアクティブなバックグラウンド フェッチのリストを取得できます。
navigator.serviceWorker.ready.then(async (swReg) => {
const ids = await swReg.backgroundFetch.getIds();
});
バックグラウンド フェッチの登録
BackgroundFetchRegistration
(上記の例では bgFetch
)は次のようになります。
プロパティ | |
---|---|
id |
string バックグラウンド フェッチ用の ID。 |
uploadTotal |
number サーバーに送信されるバイト数。 |
uploaded |
number 正常に送信されたバイト数。 |
downloadTotal |
number バックグラウンド フェッチの登録時に指定された値、または あります。 |
downloaded |
number 正常に受信されたバイト数。 この値は減少する可能性があります。たとえば、接続が切断されてダウンロードがうまくいかない場合や、 再開された場合、ブラウザはそのリソースの取得をゼロから再開します。 |
result |
次のいずれかになります。
|
failureReason |
次のいずれかになります。
|
recordsAvailable |
boolean 基になるリクエスト/レスポンスにアクセスできるか。 これが false の場合、 |
メソッド | |
abort() |
Promise<boolean> を返します。バックグラウンド フェッチを中止します。 フェッチが正常に中止された場合、返される Promise は true で解決されます。 |
matchAll(request, opts) |
戻り値Promise<Array<BackgroundFetchRecord>> リクエストを取得する 学習します。 ここでの引数は、 キャッシュ API。引数なしで呼び出すと、すべてのレコードに対する Promise が返されます。 詳しくは以下をご覧ください。 |
match(request, opts) |
Promise<BackgroundFetchRecord> を返します。上記と同じですが、次で解決されます 一致します。 |
イベント | |
progress |
uploaded 、downloaded 、result 、または
乗り継ぎ: failureReason 回。 |
進捗状況の追跡
これを行うには、progress
イベントを使用します。downloadTotal
は、使用する値が任意の値であることに
値を指定しなかった場合は 0
を返します。
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}%`);
});
リクエストとレスポンスの取得
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
は BackgroundFetchRecord
で、次のようになります。
プロパティ | |
---|---|
request |
Request 提供されたリクエスト。 |
responseReady |
Promise<Response> 取得したレスポンス。 レスポンスがまだ受信されていない可能性があるため、Promise の背後になっています。約束 取得が失敗すると拒否されます。 |
Service Worker イベント
イベント | |
---|---|
backgroundfetchsuccess |
すべてが正常に取得されました。 |
backgroundfetchfailure |
1 つ以上の取得に失敗しました。 |
backgroundfetchabort |
1 つ以上の取得に失敗しました。
これは、関連データをクリーンアップする場合にのみ有用です。 |
backgroundfetchclick |
ユーザーがダウンロード進行状況 UI をクリックした。 |
イベント オブジェクトには次のものがあります。
プロパティ | |
---|---|
registration |
BackgroundFetchRegistration |
メソッド | |
updateUI({ title, icons }) |
最初に設定したタイトルやアイコンを変更できます。これは省略可能ですが、
必要に応じて詳細なコンテキストを提供できます。この操作は、
backgroundfetchsuccess イベントと backgroundfetchfailure イベント。 |
成功/失敗への対応
progress
イベントはすでに見てきましたが、これはユーザーがページを開いている場合にのみ有用です。
できます。バックグラウンド取得の主なメリットは、ユーザーがプログラムを終了した後も動作を継続できることです。
ブラウザを閉じることもあります。
バックグラウンド フェッチが正常に完了すると、Service Worker は
backgroundfetchsuccess
イベント、event.registration
はバックグラウンド取得の登録です。
このイベントの後、フェッチ済みのリクエストとレスポンスにはアクセスできなくなります。したがって、 キャッシュ API などの場所に移動してください。
ほとんどの Service Worker イベントと同様に、event.waitUntil
を使用して、イベントがいつ発生したかを Service Worker が認識できるようにします。
確認します。
たとえば、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!' });
}());
});
失敗の原因は 1 つの 404 にとどまっているかもしれません。404 は重要ではなかったかもしれません。 上記のように、一部のレスポンスをキャッシュにコピーする価値があります。
クリックに反応する
ダウンロードの進行状況と結果を表示している UI がクリック可能になっている。backgroundfetchclick
イベント:
Service Worker でこれに対応できます。上記のように、event.registration
が背景になります
フェッチ登録します
このイベントでの一般的な処理は、ウィンドウを開くことです。
addEventListener('backgroundfetchclick', (event) => {
const bgFetch = event.registration;
if (bgFetch.result === 'success') {
clients.openWindow('/latest-podcasts');
} else {
clients.openWindow('/download-progress');
}
});
参考情報
修正: この記事の以前のバージョンでは、バックグラウンド フェッチを「ウェブ標準」と誤って表記していました。この API は現在標準のトラックには存在しません。仕様は WICG でコミュニティ グループ レポートのドラフト版として入手できます。