即使瀏覽器已關閉,推送訊息 API 也能向使用者傳送通知。許多開發人員希望能夠使用這類訊息,在未開啟瀏覽器的情況下更新及同步內容,但 API 有一項重要的限制:您必須一律針對收到的每則推播訊息顯示通知。
使用者和開發人員在使用應用程式時,可能會發現傳送推播訊息可用於同步處理使用者裝置上的資料,或是隱藏先前顯示的通知,這類功能非常實用。不過,如果允許網頁應用程式在使用者不知情的情況下,在背景執行工作,就可能遭到濫用。
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 版中,「silent-push」是唯一可用的作業類型,但您可以在規格中查閱完整的作業類型清單。另外,您還無法輕鬆提高已使用後用於測試或偵錯的預算,但您可以在 Chrome 中建立新的設定檔,做為臨時替代方案。很遺憾,您也無法使用無痕模式,因為預算 API 會在無痕模式中傳回零預算 (雖然在測試期間有導致錯誤的錯誤)。
您應該只在未來某個時間點打算執行要保留的作業時,才呼叫 reserve()
。請注意,如果您在上述範例中呼叫 reserve 但仍顯示通知,預算仍會使用。
其中一種常見用途並非只由 reserve()
啟用,也就是可從後端排定無訊息推送時間。Budget API 確實有可啟用此用途的 API,但這些 API 仍在 Chrome 中進行開發,目前僅可透過標記和 / 或來源試用啟用。
Budget API 和來源試用
網頁應用程式可採用 getBudget()
和 getCost()
這兩種方法,規劃預算用量。
在 Chrome 60 中,如果您註冊來源試用,這兩種方法都適用,但如果您想在本地測試,則可啟用「Experimental Web Platform features」flag (在 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 Repo 上提供意見回饋,或在 crbug.com 回報 Chrome 錯誤。