Push Messaging API を使用すると、ブラウザを閉じているときでも、ユーザーに通知を送信できます。多くのデベロッパーは、このメッセージングを使用して、ブラウザを開かずにコンテンツを更新、同期したいと考えていますが、この API には 1 つの重要な制限があります。受信したプッシュ メッセージごとに常に通知を表示する必要があります。
プッシュ メッセージを送信してユーザーのデバイス上のデータを同期したり、以前に表示した通知を非表示にしたりできる機能はユーザーとデベロッパーにとって大いに役立ちますが、ウェブアプリをユーザーが気付かないうちにバックグラウンドで動作できるようにすると、悪用される危険性があります。
Budget API は、ユーザーに通知することなく、デベロッパーが限定的なバックグラウンド処理(サイレント プッシュやバックグラウンド取得など)を実行できるように設計された新しい API です。Chrome 60 以降では、この API の使用を開始できます。Chrome チームは、デベロッパーからのフィードバックを心よりお待ちしております。
デベロッパーがバックグラウンドでユーザーのリソースを使用できるようにするため、ウェブ プラットフォームでは、新しい Budget API を使用して予算のコンセプトが導入されています。各サイトには、ユーザー エンゲージメントに基づいて一定の量のリソースが与えられます。ユーザーはそれをバックグラウンド アクションで消費できます。たとえば、サイレント プッシュでは、各オペレーションでバジェットが枯渇します。予算が消化されると、ユーザーが認識している状態でなければバックグラウンド アクションを実行できなくなります。ユーザー エージェントは、ヒューリスティクスに基づいてウェブアプリに割り当てられる予算を決定します。たとえば、予算の許可額をユーザー エンゲージメントにリンクできます。各ブラウザは独自のヒューリスティクスを決定できます。
要約 Budget API を使用すると、予算の予約、予算の使用、残りの予算のリストの取得、バックグラウンド オペレーションの費用の把握を行うことができます。
予算を予約しています
Chrome 60 以降では、navigator.budget.reserve()
メソッドをフラグなしで使用できます。
reserve()
メソッドを使用すると、特定のオペレーションの予算をリクエストできます。このメソッドは、予算を予約できるかどうかを示すブール値を返します。予算が予約されている場合は、バックグラウンド処理についてユーザーに知らせる必要はありません。
プッシュ通知の例では、「サイレント プッシュ」オペレーションの予算を予約できます。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 で新しいプロファイルを作成できます。残念ながら、この目的にもシークレット モードは使用できません(ただし、テスト中にエラーが発生するバグがあります)。
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'.
今後の予算枠を含めるメリットの一つは、デベロッパーがこの情報をバックエンドと共有して、サーバーサイドの動作を適応させることができることです(つまり、クライアントにサイレント プッシュの予算がある場合にのみ、プッシュ メッセージを送信して更新をトリガーします)。
オペレーションの費用を取得する
オペレーションにかかる費用を確認するには、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 のバグを報告してください。