Budget API の概要

Push Messaging API を使用すると、ブラウザが閉じられていてもユーザーに通知を送信できます。多くのデベロッパーは、このメッセージを使用して、ブラウザを開かずにコンテンツの更新や同期を行いたいと考えていますが、API には重要な制限が 1 つあります。それは、プッシュ メッセージがすべて受信されるたびに常に通知を表示する必要があることです。

プッシュ メッセージを送信してユーザーのデバイス上でデータを同期したり、以前に表示した通知を非表示にしたりできることは、ユーザーとデベロッパーにとって非常に便利ですが、ウェブアプリが不正使用の可能性があることをユーザーが認識せずにバックグラウンドで動作させることを可能にします。

Budget API は、デベロッパーがユーザーに通知せずに、制限付きのバックグラウンド処理(サイレント プッシュやバックグラウンド フェッチの実行など)を行えるように設計された新しい API です。Chrome 60 以降では、この API の使用を開始できるようになります。Chrome チームは、デベロッパーの皆様からのフィードバックをお待ちしています。

デベロッパーがバックグラウンドでユーザーのリソースを消費できるようにするため、ウェブ プラットフォームには新しい Budget API を使用した予算というコンセプトが導入されています。各サイトには、バックグラウンド アクション(各オペレーションが予算を使い果たすサイレント プッシュなど)に消費できるリソース量が、ユーザー エンゲージメントに応じて付与されます。予算がなくなると、バックグラウンド アクションは、ユーザーの目に触れることなく実行できなくなります。ユーザー エージェントは、ヒューリスティックに基づいてウェブアプリに割り当てる予算を決定します。たとえば、予算制限をユーザー エンゲージメントにリンクできます。各ブラウザは独自のヒューリスティックを決定できます。

要約: Budget API を使用すると、予算の予約、予算の使用、残り予算のリストの取得、バックグラウンド操作の費用の確認を行うことができます。

予算の予約

Chrome 60 以降では、フラグなしで navigator.budget.reserve() メソッドを使用できます。

reserve() メソッドを使用すると、特定のオペレーションの予算をリクエストできます。このメソッドは、予算を予約できるかどうかを示すブール値を返します。予算が予約されている場合、バックグラウンド処理をユーザーに通知する必要はありません。

プッシュ通知の例では、「サイレント - push」オペレーションの予算の予約を試行でき、reserve() が true で解決されると、オペレーションは許可されます。それ以外の場合は false が返され、通知を表示する必要がある

self.addEventListener('push', event => {
 const promiseChain = navigator.budget.reserve('silent-push')
   .then((reserved) => {
     if (reserved) {
       // No need to show a notification.
       return;
     }

     // Not enough budget is available, must show a notification.
     return registration.showNotification(...);
   });
 event.waitUntil(promiseChain);
});

Chrome 60 で使用できるオペレーション タイプは「サイレント プッシュ」のみですが、オペレーション タイプの詳細なリストについては仕様をご確認ください。また、使用後にテストやデバッグ用の予算を増やす簡単な方法はありませんが、一時的な回避策として、Chrome で新しいプロファイルを作成することもできます。残念ながら、シークレット モードで使用すると Budget API がゼロの予算を返すため、シークレット モードを使用することはできません(ただし、テスト中にエラーになるバグがあります)。

reserve() は、将来のいずれかの時点で予約するオペレーションを実行する場合にのみ呼び出してください。上記の例で Reserve を呼び出しても通知が表示される場合は、予算が引き続き使用されます。

reserve() だけでは有効にできない一般的なユースケースの 1 つに、バックエンドからのサイレント プッシュのスケジュール設定があります。Budget API にはこのユースケースを有効にするための API がありますが、現在も Chrome で作業が行われており、現在のところ、フラグやオリジン トライアルでのみ使用できます。

Budget API とオリジン トライアル

ウェブアプリで予算の使用を計画するには、getBudget()getCost() の 2 つの方法があります。

Chrome 60 では、オリジン トライアルに登録すれば、どちらの方法も使用できますが、テスト用にローカルで使用するには、試験運用版ウェブ プラットフォームの機能フラグ(Chrome で chrome://flags/#enable-experimental-web-platform-features を開く)を有効にします。

これらの API の使用方法を見ていきましょう。

予算を確保

利用可能な予算は、getBudget() メソッドで確認できます。一部のブラウザ(Chrome など)では、予算が時間の経過とともに減っていくため、全体像を把握できるように、将来のさまざまな時点での予算を示す BudgetStates の配列が返されます。

実行できる予算エントリを一覧表示するには:

navigator.budget.getBudget()
.then((budgets) => {
  budgets.forEach((element) => {
    console.log(\`At '${new Date(element.time).toString()}' \` +
      \`your budget will be '${element.budgetAt}'.\`);
  });
});

最初のエントリは現在の予算です。追加の値には、将来のさまざまな時点での予算が表示されます。

At 'Mon Jun 05 2017 12:47:20' you will have a budget of '3'.
At 'Fri Jun 09 2017 10:42:57' you will have a budget of '2'.
At 'Fri Jun 09 2017 12:31:09' you will have a budget of '1'.

将来の予算の許容範囲を含めるメリットの 1 つは、デベロッパーがこの情報をバックエンドと共有して、サーバーサイドの動作を調整できることです(つまり、クライアントにサイレント プッシュの予算がある場合にのみ push メッセージを送信して更新をトリガーします)。

オペレーションの費用の取得

オペレーションの費用を確認するには、getCost() を呼び出すと、そのオペレーションの reserve() を呼び出した場合に消費される予算の最大額を示す数値が返されます。

たとえば、プッシュ メッセージを受信したときに通知を表示しないコスト(つまり、サイレント プッシュのコスト)を次のコードで確認できます。

navigator.budget.getCost('silent-push')
.then((cost) => {
  console.log('Cost of silent push is:', cost);
})
.catch((err) => {
  console.error('Unable to get cost:', err);
});

執筆時点で、Chrome 60 では次のものが出力されます。

Cost of silent push is: 2

reserve() メソッドと getCost() メソッドで強調すべき点の一つは、オペレーションの実際のコストが getCost() によって返されるコストよりも低くなる可能性があることです。現在の予算が指定された費用より少ない場合は、オペレーションを予約できる場合があります。仕様の具体的な詳細は次のとおりです。

これは Chrome の現在の API です。ウェブでは、バックグラウンド取得などのバックグラウンド処理を実行する機能を必要とする新しい API が引き続きサポートされるため、Budget API を使用して、ユーザーに通知せずに実行できるオペレーションの数を管理できます。

API を使用する際は、GitHub リポジトリにフィードバックを送信するか、crbug.com で Chrome のバグを報告してください。