Webの定期的なバックグラウンド同期

ドラフト コミュニティグループ報告,

この版:
https://wicg.github.io/periodic-background-sync/index.html
課題追跡:
GitHub
編集者:
(Google)
(Google)

要旨

この仕様は、ウェブアプリケーションがバックグラウンドで定期的にデータやコンテンツを同期できる方法を説明します。

この文書のステータス

この仕様は Web Platform Incubator Community Group によって公開されました。 これは W3C 標準ではなく、W3C の標準化プロセストラック上にもありません。 W3C Community Contributor License Agreement (CLA) に基づき、限定的なオプトアウトがあり、その他の条件が適用される点にご注意ください。 W3C Community and Business Groups について詳しくはこちら。

1. はじめに

この節は規範的ではありません。

Web アプリケーションはしばしば信頼性の低いネットワーク(例:携帯電話)や寿命が不確かな環境(ブラウザが終了される、またはユーザーが離脱する可能性がある)で動作します。 そのため、Web アプリがコンテンツや状態をサーバーと同期し続けることが困難になります。

この API は、コンテンツ作成とサーバーおよび Web アプリ間のコンテンツ同期の間の時間を短縮することを目的としています。これは、Web アプリが定期的に状態やデータを同期する意図を、望む最小間隔とともに登録できるようにすることで実現します。サービスワーカーのイベントを通じて、ユーザーエージェントは定期的に Web アプリにネットワークリソースをダウンロードさせ、状態を更新させます。

この API はサービスワーカーに依存しているため、この API が提供する機能は セキュアコンテキスト でのみ利用可能です。

1.1.

ブラウジングコンテキスト から最小間隔を 1 日にして定期的なバックグラウンド同期を登録する例:

async function registerPeriodicNewsCheck() {
  const registration = await navigator.serviceWorker.ready;
  try {
    await registration.periodicSync.register('fetch-news', {
      minInterval: 24 * 60 * 60 * 1000,
    });
  } catch {
    console.log('Periodic Sync could not be registered!');
  }
}

periodicsync イベント に対して サービスワーカー 内で反応する例:

self.addEventListener('periodicsync', event => {
  event.waitUntil(fetchAndCacheLatestNews());
});

上の例では、fetchAndCacheLatestNews は開発者が定義した関数で、サーバーから最新のニュース記事を取得してローカルに保存します。例えばオフラインでの利用のために Cache API を使用して保存します。

2. 概念

periodicsync イベントが、定期同期登録 registration に対して発火されたとき、そのイベントは バックグラウンドで実行されるとみなされるのは、サービスワーカークライアントのうち、フレームタイプが "top-level", "auxiliary" または "nested" のいずれかであるものが、オリジン、すなわちサービスワーカー登録のうち、 registrationに関連付けられたもののオリジンに存在しない場合である。

3. Service Worker 登録への拡張

service worker registration にはさらに以下が含まれます:

4. 構成要素

4.1. 定期同期登録

A periodic sync registration は次の要素で構成されます:

service worker registration、これは service worker registration です。

tag、これは DOMString です。

注: Periodic Background Sync は Background Sync と名前空間を共有しないため、ある origin は同じタグで両方のタイプの登録を持つことができます。

minimum interval(long long)は、定期同期が発生する最小間隔をミリ秒単位で指定するために使用されます。minimum interval はユーザーエージェントへの提案です。

注: 実際に periodicsync イベント が発火する間隔は、これと同じかそれ以上でなければなりません。

anchor time(タイムスタンプ)は、この periodicsync イベント がこの periodic sync registration に対して以前に発火した時刻、または初回登録の時刻です。

state は "pending"、"firing"、"suspended"、または "reregistered-while-firing" のいずれかで、初期値は "pending" に設定されます。

4.2. 定期同期スケジューラ

periodic sync schedulerperiodicsync イベント の発火スケジューリングを担当します。

これらのトリガーに応じて、スケジューラは将来の適切な時刻に periodicsync イベント を発火させるための遅延処理をスケジュールするか、またはそのスケジュールをキャンセルします。

スケジューラは次を維持します:

effective minimum sync interval for origin originorigin)は、minimum periodic sync interval for any origin に、その origin に対してユーザーエージェントが定義する量を加えたものです。

注: ユーザーエージェントが定義する量は、ユーザーのその origin へのエンゲージメント量に基づく可能性があります。この値は effective minimum sync interval for origin が呼ばれるたびに異なる場合があります。

スケジューラは 定期同期登録の処理 を行います。

注: ブラウザはリソース節約のために、アクティブな定期同期登録 が存在しない場合にこの処理ループを一時停止することがあります。

4.3. 定数

セクション § 5 プライバシーに関する考慮事項 および § 6 リソース使用 で推奨されているように、ユーザーエージェントは次も定義すべきです:

minimum periodic sync interval across originsminimum periodic sync interval for any origin 以上でなければなりません。未定義の場合、これらは 43200000(ミリ秒単位で 12 時間)に設定されます。

注: 頻度に対する 2 つの上限が必要です。なぜなら、各 origin ごとに minimum periodic sync interval for any origin による制限を順守しても、ブラウザが periodicsync イベント を非常に頻繁に発火してしまうことがあるからです。例えば、多くの異なる origin に対する periodic sync registrations が存在する場合などです。minimum periodic sync interval across origins はこれらのイベントが発火する頻度に対するグローバルな上限を保証します。

ユーザーエージェントは各 periodicsync イベント に許される 最大再試行回数(数値)を定義してもよいです。これを選定する際、ユーザーエージェントは 最大再試行回数 を試行するのに必要な時間が minimum periodic sync interval for any origin より桁違いに短いことを保証するべきです。未定義の場合、この数値はゼロです。

5. プライバシーに関する考慮事項

5.1. 権限

定期バックグラウンド同期は、PermissionState が、PermissionDescriptor のうち、name"periodic-background-sync" であるものに対するものであり、granted である場合にのみ利用できる。 さらに、ユーザーエージェントは、ユーザーが定期バックグラウンド同期を無効にするための手段を提供するべきである。 定期バックグラウンド同期が無効になっている場合、periodicsync イベントを、定期 同期登録のうち、この権限の影響を受けるものに対して配送してはならない。(§ 7.2 権限の取り消しへの対応を参照)。

5.2. 位置情報の追跡

periodicsync イベント内のフェッチ要求は、バックグラウンド で実行されている間、ユーザーがページを離れた後でも、クライアントの IP アドレスをサーバーに明らかにする可能性がある。ユーザー エージェントは、再試行回数とperiodicsync イベントの継続時間に上限を設け、追跡を制限することで、 ウェブサイトがユーザーの位置を追跡できる時間を短縮するべきである。さらに、ユーザーエージェントは、持続的な 位置追跡を制限するため、periodicsync イベントの頻度に上限を設け、単一のオリジンについても、複数のオリジンにまたがる場合についても、その上限を適用するべきである。

5.3. 履歴の漏洩

periodicsync event 内で、バックグラウンドで 行われる fetch リクエストは、periodic sync registration を作成したネットワークとは別のネットワーク上にあるミドルボックスにクライアントのナビゲーション履歴に関する何らかの情報を明らかにする可能性があります。例えば、クライアントが https://example.com を訪問して periodicsync event を登録したとしても、実装によってはユーザーがページから離れてネットワークを切り替えた後まで発火しない場合があります。新しいネットワーク上のミドルボックスは、periodicsync event によって行われる fetch リクエストを見る可能性があります。fetch リクエストは HTTPS で行われるためリクエストの内容は漏れませんが、フェッチ先やドメインは(DNS ルックアップやリクエストの IP アドレスを通じて)漏れる可能性があります。閲覧履歴のこのような漏洩を防ぐために、ユーザーエージェントは periodicsync eventsperiodic sync registration が行われたネットワーク上でのみ発火させることを選択してもよいですが、その場合は同期を機会的に行えなくなるため使い勝手が低下する点に注意する必要があります。

6. リソース使用

この節は規範的ではありません。

ウェブサイトは、periodicsync event を処理するときにネットワークからリソースをダウンロードすることが多くあります。基盤となるオペレーティングシステムは、これらのイベントをディスパッチするためにユーザーエージェントを起動し、イベントの処理を許可するためにあらかじめ定義された期間だけアプリを動作させ続ける場合があり、どちらもバッテリー消費を引き起こします。ユーザーエージェントは、ユーザーが離れた後のウェブサイトによるリソース使用を制限するために、これらのイベントの継続時間と頻度に上限を設けるべきです。

大きなリソースは、background fetchBackgroundFetchManager インターフェースを介して登録することでダウンロードするべきです。

加えて、ユーザーエージェントは origin に対するユーザーのエンゲージメントや、データ節約モードなどデータ消費を一時的に抑えるユーザーの意思表示を考慮して、periodicsync events の頻度を調整するべきです。

7. アルゴリズム

7.1. 定期同期登録の処理

ユーザーエージェントが開始したとき、以下の手順を並列で実行します:
  1. 次の処理を繰り返します:

    1. minimum periodic sync interval across origins を待ちます。

    2. firedPeriodicSync を false にします。

    3. firedPeriodicSync が false の間:

      1. ユーザーエージェントが定義する一定時間を待ちます。

        注: これは異なる periodic sync registrations の同期を単一のデバイス起動にまとめるために使えます。

      2. online になるまで待ちます。

      3. 未だunregisteredでない各service worker registration registrationについて、 以下の手順をキューに追加し、registrationperiodic sync 処理キューに追加する:

        1. originorigin とします。これは periodicSyncRegistrationservice worker registration に関連付けられています。

        2. time of last fire[origin] + effective minimum sync interval for origin(origin) が現在時刻より大きい場合、continue します。

        3. registrationactive periodic sync registrations にある各 periodic sync registration periodicSyncRegistration について:

          1. state が "pending" でない場合、continue します。

          2. periodicSyncRegistrationanchor time + periodicSyncRegistrationminimum interval が現在時刻より大きい場合、continue します。

          3. firedPeriodicSync を true に設定します。

          4. periodicsync event を発火 します(対象: periodicSyncRegistration)。

7.2. 権限取り消しへの対応

, 出现一种完全不错呢,我就不一样的, 然后开? 尤其 取り消しに対応する対象が、name として "periodic-background-sync" を持ち、オリジン origin に対する権限である場合、ユーザーエージェントは次の手順をキューに追加しなければならず、追加先は定期同期 処理キューとする:
  1. 定期同期登録 registration のそれぞれについて、アクティブな定期同期登録 に含まれ、そのサービスワーカー 登録に関連付けられたオリジンorigin と同じであるものを対象として、次を行う:

    1. registrationアクティブな定期同期 登録から削除する。

8. API の説明

8.1. ServiceWorkerGlobalScope インターフェースへの拡張

partial interface ServiceWorkerGlobalScope {
    attribute EventHandler onperiodicsync;
};

8.2. ServiceWorkerRegistration インターフェースへの拡張

ServiceWorkerRegistration/periodicSync

In only one current engine.

FirefoxNoneSafariNoneChrome80+
OperaNoneEdge80+
Edge (Legacy)NoneIENone
Firefox for AndroidNoneiOS SafariNoneChrome for Android80+Android WebView80+Samsung Internet13.0+Opera MobileNone
[Exposed=(Window,Worker)]
partial interface ServiceWorkerRegistration {
  readonly attribute PeriodicSyncManager periodicSync;
};
ServiceWorkerRegistration には、定期同期マネージャーPeriodicSyncManager)がある。

periodicSync 属性の取得子は、コンテキストオブジェクト定期同期マネージャーを返さなければならず、その初期値は、 新しい PeriodicSyncManager であり、その サービスワーカー登録は、 コンテキストオブジェクトサービスワーカー登録である。

8.3. PeriodicSyncManager インターフェース

PeriodicSyncManager

In only one current engine.

FirefoxNoneSafariNoneChrome80+
Opera67+Edge80+
Edge (Legacy)NoneIENone
Firefox for AndroidNoneiOS SafariNoneChrome for Android80+Android WebView80+Samsung Internet13.0+Opera Mobile57+
[Exposed=(Window,Worker)]
interface PeriodicSyncManager {
    Promise<undefined> register(DOMString tag, optional BackgroundSyncOptions options = {});
    Promise<sequence<DOMString>> getTags();
    Promise<undefined> unregister(DOMString tag);
};

dictionary BackgroundSyncOptions {
    [EnforceRange] unsigned long long minInterval = 0;
};
A PeriodicSyncManager has a service worker registration (a service worker registration).

PeriodicSyncManager/register

In only one current engine.

FirefoxNoneSafariNoneChrome80+
Opera67+Edge80+
Edge (Legacy)NoneIENone
Firefox for AndroidNoneiOS SafariNoneChrome for Android80+Android WebView80+Samsung Internet13.0+Opera Mobile57+
この register(tag, options) メソッドは、呼び出されたとき、新しいプロミス promise を返し、次の手順をキューに追加しなければならず、追加先は定期同期 処理キューとする:
  1. serviceWorkerRegistration を、サービスワーカー 登録のうち、コンテキスト オブジェクトPeriodicSyncManagerに関連付けられたものとする。

  2. serviceWorkerRegistrationアクティブワーカーが null の場合、却下promise に対して InvalidStateError を伴って行い、これらの手順を中止する。

  3. PermissionState が、PermissionDescriptor のうち、name"periodic-background-sync" であるものに対するものであり、granted でない場合、却下promise に対して NotAllowedError を伴って行い、これらの手順を中止する。

  4. isBackground を、ブール値の true とする。

  5. client を、サービスワーカークライアントのうち、 serviceWorkerRegistrationオリジンに対応するもののそれぞれとして、次を行う:

    1. clientフレームタイプが "top-level" または "auxiliary" の場合、isBackground を false に設定する。

  6. isBackground が true の場合、却下promise に対して InvalidAccessError を伴って行い、これらの手順を中止する。

  7. currentRegistration を、定期同期 登録のうち、serviceWorkerRegistrationアクティブな定期同期登録 に含まれ、そのtagtag に等しいものが存在する場合はそのもの、存在しない場合は null とする。

  8. currentRegistration が null の場合:

    1. newRegistration を、新しい定期同期登録とする。

    2. newRegistrationtagtag に設定する。

    3. newRegistration最小間隔optionsminInterval メンバーに設定する。

    4. newRegistration状態を "pending" に設定する。

    5. newRegistrationサービスワーカー 登録serviceWorkerRegistration に設定する。

    6. newRegistrationアンカー時刻を、現在を表すタイムスタンプ に設定する。

    7. newRegistrationserviceWorkerRegistrationアクティブな定期同期 登録に追加する。

    8. 解決する対象を promise とする。

  9. それ以外の場合:

    1. currentRegistration最小間隔optionsminInterval メンバーと異なる場合:

      1. currentRegistration最小 間隔optionsminInterval メンバーに設定する。

    2. それ以外の場合、currentRegistration状態が "firing" なら、 serviceWorkerRegistration状態を "reregistered-while-firing" に設定する。

    3. 解決する対象を promise とする。

PeriodicSyncManager/getTags

In only one current engine.

FirefoxNoneSafariNoneChrome80+
Opera67+Edge80+
Edge (Legacy)NoneIENone
Firefox for AndroidNoneiOS SafariNoneChrome for Android80+Android WebView80+Samsung Internet13.0+Opera Mobile57+
この getTags() メソッドは、呼び出されたとき、新しいプロミス promise を返し、次の手順をキューに追加しなければならず、追加先は定期同期 処理キューとする:
  1. serviceWorkerRegistration を、サービスワーカー 登録のうち、コンテキスト オブジェクトPeriodicSyncManagerに関連付けられたものとする。

  2. currentTags を、新しいリストとする。

  3. registration を、serviceWorkerRegistrationアクティブな定期同期登録の各要素として、それぞれについて、末尾に追加する対象を registrationtag とし、追加先を currentTags とする。

  4. 解決する対象を promise、その値を currentTags とする。

PeriodicSyncManager/unregister

In only one current engine.

FirefoxNoneSafariNoneChrome80+
Opera67+Edge80+
Edge (Legacy)NoneIENone
Firefox for AndroidNoneiOS SafariNoneChrome for Android80+Android WebView80+Samsung Internet13.0+Opera Mobile57+
この unregister(tag) メソッドは、呼び出されたとき、新しいプロミス promise を返し、次の手順をキューに追加しなければならず、追加先は定期同期 処理キューとする:
  1. serviceWorkerRegistration を、サービスワーカー 登録のうち、コンテキスト オブジェクトPeriodicSyncManagerに関連付けられたものとする。

    1. currentRegistration を、定期同期登録のうち、 serviceWorkerRegistrationアクティブな定期同期 登録に含まれ、そのtagtag に等しいものが 存在する場合はそのもの、存在しない場合は null とする。

    2. currentRegistration が null でない場合、currentRegistrationserviceWorkerRegistrationアクティブな定期同期 登録から削除する。

    3. 解決する対象を promise とする。

8.4. periodicsync イベント

PeriodicSyncEvent/PeriodicSyncEvent

現在、1つのエンジンのみでサポートされています。

FirefoxなしSafariなしChrome80+
Opera67+Edge80+
Edge (レガシー)なしIEなし
Android 版 FirefoxなしiOS SafariなしAndroid 版 Chrome80+Android WebView80+Samsung Internet13.0+Opera Mobile57+

PeriodicSyncEvent

現在、1つのエンジンのみでサポートされています。

FirefoxなしSafariなしChrome80+
Opera67+Edge80+
Edge (レガシー)なしIEなし
Android 版 FirefoxなしiOS SafariなしAndroid 版 Chrome80+Android WebView80+Samsung Internet13.0+Opera Mobile57+
dictionary PeriodicSyncEventInit : ExtendableEventInit {
    required DOMString tag;
};

[Exposed=ServiceWorker]
interface PeriodicSyncEvent : ExtendableEvent {
    constructor(DOMString type, PeriodicSyncEventInit init);
    readonly attribute DOMString tag;
};

PeriodicSyncEvent/tag

現在、1つのエンジンのみでサポートされています。

FirefoxなしSafariなしChrome80+
Opera67+Edge80+
Edge (レガシー)なしIEなし
Android 版 FirefoxなしiOS SafariなしAndroid 版 Chrome80+Android WebView80+Samsung Internet13.0+Opera Mobile57+
PeriodicSyncEventtagtag)を持ちます。 tag 属性は初期化時に設定された値を返さなければなりません。

8.4.1. periodicsync イベントを発火する

注記: ユーザーエージェントは、PeriodicSyncEvent のライフタイム延長および実行時間に対し、一般的な ExtendableEvent よりも厳しい制限時間を課す場合があります。特に、PeriodicSyncEvent の再試行には大幅に短いタイムリミットが設けられる場合があります。
periodicsync イベントを 発火する対象を定期同期登録 registration とする場合、 ユーザーエージェントは次の手順を実行しなければならない:
  1. serviceWorkerRegistrationregistrationサービスワーカー 登録とする。

  2. registrationserviceWorkerRegistrationアクティブな定期同期登録に 含まれなくなっている場合、これらの手順を中止する。

  3. 表明: registration状態は "pending" である。

  4. retryCount を 0 とする。

  5. registration状態を "firing" に設定する。

  6. true である間、次を繰り返す:

    1. continue を false とする。

    2. success を false とする。

    3. 機能イベントの発火を "periodicsync" について、PeriodicSyncEvent を使用し、serviceWorkerRegistration 上で、tagregistrationtagに設定して行う。 dispatchedEvent を、ExtendableEventとし、 配送されたperiodicsync イベントを表すものとし、次の手順を dispatchedEventを用いて実行する:

    4. waitUntilPromise を、すべての完了を待機した結果とし、待機対象を dispatchedEvent存続期間延長プロミスとする。

    5. 履行waitUntilPromise に対して行われたとき、 次の手順で反応する:

      1. success を true に設定する。

      2. continue を true に設定する。

    6. 却下に反応する場合、却下waitUntilPromise に対して行われたとき、 次の手順を実行する:

      1. continue を true に設定する。

    7. 並行して:

      1. continue が true になるまで待機する。

      2. origin を、オリジンのうち、 registrationサービスワーカー 登録に関連付けられたものとする。

      3. success が true の場合、最終 発火時刻を、キー origin について現在時刻に設定する。

      4. success が true であるか、retryCount最大再試行回数より大きいか、または registration の state が "reregistered-while-firing" である場合:

        1. registration状態を "pending" に設定する。

        2. registrationアンカー時刻 を、現在を表すタイムスタンプに設定する。

        3. これらの手順を中止する。

    8. retryCount を 1 増加させる。

    9. retryCount に基づく短いバックオフ時間だけ待機する。

適合性

文書の慣例

適合要件は、記述的な主張と RFC 2119 の用語を組み合わせて示されています。 この文書の規範的な部分で “MUST”, “MUST NOT”, “REQUIRED”, “SHALL”, “SHALL NOT”, “SHOULD”, “SHOULD NOT”, “RECOMMENDED”, “MAY”, “OPTIONAL” のキーワードは RFC 2119 に記載されている通りに解釈するものとします。 ただし、可読性のため、これらの単語は本仕様ではすべて大文字で表記されません。

この仕様書内のテキストはすべて規範的です。明示的に非規範的と示されたセクション、例、注記を除きます。[RFC2119]

この仕様の例は “for example” との導入文、または class="example" により規範テキストと区別されています。以下のようになります:

これは情報提供例のひとつです。

情報提供用の注記は "Note" で始まり、class="note" で規範テキストと区別され、下記のようになります:

注記: これは情報提供用の注記です。

適合するアルゴリズム

アルゴリズムの一部として命令形で記述されている要件(例えば "先頭からすべての空白文字を削除する" や "false を返し、これらの手順を中止する" など)は、そのアルゴリズムの冒頭で使われているキーワード("must", "should", "may" など)に従って解釈されます。

アルゴリズムまたは特定手順として記述された適合要件は、同等の結果となる限り任意の方法で実装可能です。 特に本仕様で定義しているアルゴリズムは理解しやすいように作成されており、高速性を意図していません。 実装者は最適化を推奨します。

索引

この仕様によって定義された用語

参照により定義される用語

参考文献

規範的な参考文献

[BACKGROUND-FETCH]
Background Fetch. cg-draft. URL: https://wicg.github.io/background-fetch/
[DOM]
Anne van Kesteren. DOM Standard. Living Standard. URL: https://dom.spec.whatwg.org/
[HTML]
Anne van Kesteren; et al. HTML Standard. Living Standard. URL: https://html.spec.whatwg.org/multipage/
[INFRA]
Anne van Kesteren; Domenic Denicola. Infra Standard. Living Standard. URL: https://infra.spec.whatwg.org/
[PERMISSIONS]
Mounir Lamouri; Marcos Caceres; Jeffrey Yasskin. Permissions. 2020年7月20日. WD. URL: https://www.w3.org/TR/permissions/
[RFC2119]
S. Bradner. Key words for use in RFCs to Indicate Requirement Levels. 1997年3月. Best Current Practice. URL: https://tools.ietf.org/html/rfc2119
[SERVICE-WORKERS-1]
Alex Russell; et al. Service Workers 1. 2019年11月19日. CR. URL: https://www.w3.org/TR/service-workers-1/
[WEB-BACKGROUND-SYNC]
Web Background Synchronization. cg-draft. URL: https://wicg.github.io/background-sync/spec/
[WebIDL]
Boris Zbarsky. Web IDL. 2016年12月15日. ED. URL: https://heycam.github.io/webidl/

IDL 索引

partial interface ServiceWorkerGlobalScope {
    attribute EventHandler onperiodicsync;
};

[Exposed=(Window,Worker)]
partial interface ServiceWorkerRegistration {
  readonly attribute PeriodicSyncManager periodicSync;
};

[Exposed=(Window,Worker)]
interface PeriodicSyncManager {
    Promise<undefined> register(DOMString tag, optional BackgroundSyncOptions options = {});
    Promise<sequence<DOMString>> getTags();
    Promise<undefined> unregister(DOMString tag);
};

dictionary BackgroundSyncOptions {
    [EnforceRange] unsigned long long minInterval = 0;
};

dictionary PeriodicSyncEventInit : ExtendableEventInit {
    required DOMString tag;
};

[Exposed=ServiceWorker]
interface PeriodicSyncEvent : ExtendableEvent {
    constructor(DOMString type, PeriodicSyncEventInit init);
    readonly attribute DOMString tag;
};