Budget API 簡介

Push Messaging API 讓我們即使瀏覽器關閉也能傳送通知給使用者。許多開發人員都希望能使用這些訊息,在不開啟瀏覽器的情況下更新和同步處理內容,但 API 有一項重要限制:每當收到的每則推送訊息都必須顯示通知。

能夠傳送推送訊息以同步處理使用者裝置上的資料,或隱藏先前顯示的通知,對使用者和開發人員來說非常實用,但允許網頁應用程式在背景執行,卻使用者不知情,不會濫用。

Budget API 是一個新的 API,可讓開發人員在不通知使用者的情況下執行有限的背景工作,例如無訊息推送或執行背景擷取。您可以在 Chrome 60 以上版本中開始使用這個 API,且 Chrome 團隊迫不及待想收到開發人員的意見回饋。

為了讓開發人員在背景運用使用者的資源,網路平台導入了新的預算 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 版中,「silent-push」是唯一可用的作業類型,但您可以在規格中查看完整作業類型的完整清單。在 Chrome 60 版本使用後,也無法輕鬆提高預算以便進行測試或偵錯,但做為暫時性的解決方法,您可以在 Chrome 中建立新的設定檔。很遺憾,預算 API 在無痕模式中會傳回零 (儘管在測試期間錯誤導致發生錯誤),因此無法使用無痕模式。

建議您只在要執行保留的作業的某個時間點時呼叫 reserve()。請注意,如果您在上述範例中呼叫了預訂,但系統仍顯示通知,則系統仍會使用預算。

無法單獨啟用 reserve() 的常見用途之一,就是從後端排定無訊息推送作業。針對此使用情境,Budget API 提供的 API 仍為啟用此用途,但其仍在 Chrome 中運作,且目前僅適用於旗標和 / 或來源試用

預算 API 和來源試用

網頁應用程式可使用 getBudget()getCost() 這兩種方法規劃預算的用量。

在 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,因此您可以使用預算 API 來管理可執行的作業數量,而不必通知使用者。

使用 API 時,請在 GitHub 存放區中提供意見回饋,或是前往 crbug.com 回報 Chrome 錯誤。