利用服務工作者,Progressive Web App (PWA) 可以在背景工作,即使使用者未使用該應用程式,也能提供更佳的離線體驗。
請考慮以下使用情境:
- 一款電子郵件應用程式,讓使用者能隨時撰寫訊息並發送,即使離線也能使用。
- 一個每天抓取新文章的新聞應用程式,讓使用者在打開應用程式時可以閱讀。
- 一款讓使用者下載歌曲並離線聆聽的音樂應用程式。
這三種使用情境皆可透過以下 API 實現 PWA:
- 背景同步 API
- 週期性背景同步 API
- 背景擷取 API
雖然這些 API 名稱相似,但本質上有所不同。
詳細內容:
- 使用背景同步 API 來同步資料與伺服器
- 使用 Periodic Background Sync API 定期取得新鮮內容
- 當應用程式或服務工作者未執行時,使用背景擷取 API 來擷取大型檔案
- 使用 App Badging API 和通知 API 來重新吸引用戶
使用背景同步 API 來同步資料與伺服器
使用背景同步 API,讓使用者即使在離線狀態下也能繼續使用應用程式並執行相關操作。
例如,電子郵件應用程式可以讓使用者隨時撰寫並發送訊息。 應用程式前端可以立即嘗試發送訊息,若裝置離線,服務人員可偵測失敗請求,並利用背景同步 API 延後任務直到連線完成。
另一個使用背景同步 API 的例子是為使用者在背景載入內容。
注意事項
背景同步 API 應該用於少量資料。 背景同步 API 要求服務工作者在資料傳輸的整個過程中都處於活著狀態。 背景同步 API 不應該用來擷取大型檔案,因為裝置可能會為了節省電池壽命而終止服務人員。 相反地,請使用 背景擷取 API。
請檢查是否有支援
背景同步 API 在 Microsoft Edge 中可用,但你應該確認背景同步 API 在你應用程式運行的其他瀏覽器和裝置上是否支援。 為了確保支援背景同步 API,請測試該 ServiceWorkerRegistration 物件是否具備以下 sync 屬性:
navigator.serviceWorker.ready.then(registration => {
if (registration.sync) {
// Background Sync is supported.
} else {
// Background Sync isn't supported.
}
});
欲了解更多介面資訊 ServiceWorkerRegistration ,請參閱 MDN 的 ServiceWorkerRegistration 。
請求同步
第一步是申請同步。這可以由你的應用程式前端或服務人員完成。
- 當你想讓使用者之後負責同步時,向前端請求同步是很好的選擇。
- 當你希望讓使用者能透明時,向服務工作者請求同步是很好的選擇。 此時,服務工作者可偵測失敗的取回請求並立即請求同步。
要請求同步,你需要 ServiceWorkerRegistration 一個 和 一個標籤名稱。 從應用程式前端程式碼中,請執行以下操作:
async function requestBackgroundSync() {
const registration = await navigator.serviceWorker.ready;
await registration.sync.register('my-tag-name');
}
或者,服務人員可以這麼做:
async function requestBackgroundSync() {
await self.registration.sync.register('my-tag-name');
}
my-tag-name上述字串應該是唯一標籤,用來識別這個同步請求,這樣才能執行多個請求。
React 對同步事件
一旦連線可用且服務工作者正在運行, sync 就會傳送事件給服務工作者,讓服務工作者能利用該事件同步所需的資料。
sync此活動可透過以下代碼收聽:
self.addEventListener('sync', event => {
if (event.tag === 'my-tag-name') {
event.waitUntil(doTheWork());
}
});
在上述範例程式碼中,服務工作者中新增了一個 sync 事件監聽器。 當呼叫監聽器時,程式碼會檢查該標籤是否是前端註冊的,然後呼叫 doTheWork。 此函式預期會回傳 Promise。
通常,這個 doTheWork 函式會將使用者離線時無法傳送的資訊傳送到伺服器。 將這些資訊從前端儲存到 IndexedDB 儲存中可能很有用,方便日後執行時從服務工作者 doTheWork 那裡取得。
欲了解更多關於 Sync 事件、、及 ServiceWorkerRegistration介面的 SyncManager 資訊,請參閱 背景同步草案規範 及 背景同步 API 文件。
示範應用程式:PWA 背景同步
PWA Background Sync 是一款示範應用程式,利用 Background Sync API 在使用者離線時稍後擷取資訊:
- /pwa-background-sync/ - 說明文件與原始碼。
- PWA 背景同步 API 示範 - 現場示範。
使用示範版:
請在新視窗或分頁中進入 PWA 背景同步 API 示範 。
安裝應用程式:
在地址欄中,點擊 可用應用程式。安裝 PWA 背景同步 API 示範 (應用程式
) 按鈕。Edge會開啟 安裝PWA背景同步API示範 對話框。
點擊 安裝 按鈕。
打開 了 PWA 檔案處理器的示範 應用程式視窗。 應用程式 安裝 對話框會打開。
點擊 允許 按鈕。
PWA 背景同步 API 示範應用程式會在專用視窗中開啟。 Windows 應用程式 對話框會提示是否將應用程式釘選到工作列。
點擊 「是」 按鈕。
使用連接網路的應用程式:
在已安裝的 PWA 背景同步 API 示範 應用程式中,在 留言 文字框輸入留言,例如 「Hello」,然後點擊 「發送 」按鈕。
訊息已經發送。 您輸入的訊息顯示在 留言 文字框下方,初始狀態為 「發送中」,接著顯示「 已發送✅」狀態:
斷開網路:
在應用程式視窗中右鍵點擊,然後選擇 檢查。
DevTools 會以專用視窗開啟。
在 DevTools 中,選擇 Network (
) 工具。在網路限速下拉選單中,選擇「離線」而不是「無限速」:
網路 標籤會 新增一個警告圖示,提醒你有網路限速問題。
使用應用程式,斷開網路連線:
在已安裝的 PWA 背景同步 API 示範 應用程式中,在 留言 文字框中輸入留言,例如 再次輸入 Hello,然後點擊 「發送 」按鈕。
你輸入的訊息會出現,先顯示「發送中」,接著又顯示「失敗」。❌ 「 嘗試再發送 」按鈕會出現在訊息矩形內:
點擊「 嘗試再發送 」按鈕。
在訊息矩形內,狀態會變成 稍後再試🛜,且「 嘗試再發送 」按鈕也消失了:
如果狀態仍是 失敗❌,你可以重置服務工人,讓狀態變成 「稍後嘗試」🛜 ,當適當時機:
在 DevTools 中,選擇 應用程式 (
) 工具。在左側的導覽窗格中,選擇 服務人員,然後在右上角點選 取消註冊。
在應用程式視窗中,右鍵點擊網頁,然後選擇 重新整理。
連接網路:
在專用的 DevTools 視窗裡,網路 限速 下拉選單,而不是 離線,而是選擇 「無限速」。
網路 分頁 中的降速警告圖示已被移除。
使用應用程式,重新連接網路:
切換到已安裝的 PWA 背景同步 API 示範 應用程式。
顯示狀態為 已發送✅:
可選擇性地,在網頁中右鍵點擊,然後選擇 重新整理。
訊息會被刪除。
除錯背景與 DevTools 同步
要測試背景同步程式碼,你不必先離線再上線,再等 Microsoft Edge 觸發 sync 事件。 相反地,DevTools 讓你模擬背景同步事件。
模擬事件 sync :
- 開啟 DevTools (F12) 。
- 選擇 應用程式>服務工作者。
- 在 同步 輸入欄位輸入你註冊同步時使用的標籤名稱。
- 選擇 同步 按鈕。
你也可以在 DevTools 中記錄應用程式產生的背景同步活動,具體如下:
- 開啟 DevTools (F12) 。
- 選擇 應用程式>背景同步。
- 選擇 開始記錄事件。
同步註冊與派遣顯示在事件日誌表中:
使用 Periodic Background Sync API 定期取得新鮮內容
週期性背景同步 API 讓 PWA 能在背景定期擷取新鮮內容,使用者在之後再次開啟應用程式時能立即存取。
使用 Periodic Background Sync API,PWA 在使用者使用應用程式時,無需下載新內容 (,例如新文章) 。 下載內容可能會拖慢體驗,因此建議在更方便的時間取回內容。
在已知網路上進行週期性同步
週期性同步只會發生在裝置位於已知網路 (也就是該裝置先前已連接過的網路時) 。
Microsoft Edge 會根據使用者使用該應用程式的頻率來限制同步頻率。
請檢查是否有支援
為了檢查這個 API 是否在你應用程式運行的瀏覽器和裝置中被支援,請測試該 ServiceWorkerRegistration 物件是否有以下 periodicSync 屬性:
navigator.serviceWorker.ready.then(registration => {
if (registration.periodicSync) {
// Periodic Background Sync is supported.
} else {
// Periodic Background Sync isn't supported.
}
});
請向使用者徵求許可
定期背景同步需要使用者的許可。 申請此權限僅發生一次,針對特定應用程式。
若要請求使用者執行週期性背景同步的權限,請使用權限 API,如下:
const status = await navigator.permissions.query({name: 'periodic-background-sync'});
if (status.state === 'granted') {
// Periodic background sync can be used.
} else {
// Periodic background sync cannot be used.
}
欲了解更多關於 Permissions API,請參閱 MDN 的 Permissions API 。
暫存一個週期性同步
要註冊週期性同步,你需要定義最小間隔和唯一的標籤名稱。 獨特的標籤名稱允許註冊多個週期性背景同步。
async function registerPeriodicSync() {
await registration.periodicSync.register('get-daily-news', {
minInterval: 24 * 60 * 60 * 1000
});
}
上述代碼中使用的數字 minInterval 相當於毫秒的 1 天。 這僅為最低間隔,Microsoft Edge 在通知服務人員定期同步事件前會考慮其他因素,例如網路連線狀況及使用者是否定期使用該應用程式。
React 對週期性同步事件
當 Microsoft Edge 決定執行週期同步的好時機時,Microsoft Edge 會 periodicsync 向你的服務工作者發送事件。 你可以用註冊同步時指定的標籤名稱來處理這個 periodicsync 事件。
self.addEventListener('periodicsync', event => {
if (event.tag === 'get-daily-news') {
event.waitUntil(getDailyNewsInCache());
}
});
這個 getDailyNewsInCache 函式是你的服務工作者可以從伺服器擷取新內容並儲存在快取中。 此函式預期會回傳一個 Promise,表示同步是否成功或失敗。
關於事件 PeriodicSync 、該 ServiceWorkerRegistration及介面 PeriodicSyncManager 的更多資訊,請參見:
- 網頁週期性背景同步 - 草案規範。
- 網頁週期性背景同步 API。
示範應用程式:DevTools 技巧
DevTools Tips 是一個使用 Periodic Background Sync API 的 PWA。 [DevTools Tips] PWA 每天擷取新的開發者工具提示並存入快取,讓使用者下次開啟應用程式時,無論是否在線都能存取。
去 GitHub 查看原始碼。 特別是,應用程式會在 registerPeriodicSync 函式中登錄週期同步。
服務人員代碼是應用程式監periodicsync聽事件的地方。
除錯定期背景同步與 DevTools
你可以用 DevTools 模擬 periodicsync 事件,而不是等到最短的間隔。
模擬事件:
- 開啟 DevTools (F12) 。
- 選擇 應用程式>服務工作者。
- 在週期 同步 輸入欄位輸入你註冊週期同步時使用的標籤名稱。
- 選擇 週期性同步 按鈕。
你也可以在 DevTools 中記錄應用程式產生的週期性背景同步活動:
- 開啟 DevTools (F12) 。
- 選擇 應用程式>週期性背景同步。
- 選擇 開始記錄事件。
週期性同步註冊與派遣會出現在事件日誌表中。
當應用程式或服務工作者未執行時,使用背景擷取 API 來擷取大型檔案
背景擷取 API 允許 PWA 完全委派大量資料下載至瀏覽器引擎。 這樣一來,應用程式和服務人員在下載過程中就不必一直運行。
這個 API 對於讓使用者下載大型檔案的應用程式非常有用, (像是音樂、電影或播客,) 離線使用。 因為下載工作交給瀏覽器引擎,而瀏覽器引擎懂得如何處理連線不穩定甚至完全斷線,因此可以在需要時暫停並繼續下載。
請檢查是否有支援
要檢查此 API 是否支援,請測試建構子是否 BackgroundFetchManager 存在於全域物件上:
if (self.BackgroundFetchManager) {
// Background Fetch is supported.
} else {
// Background Fetch isn't supported.
}
開始背景擷取
要開始背景擷取:
navigator.serviceWorker.ready.then(async registration => {
const fetch = await registration.backgroundFetch.fetch('my-download-id',
fileUrls, options);
});
上方應該 my-download-id 是這個背景擷取的唯一字串識別碼。
fileUrls 是要下載的檔案清單,這將是一個字串 URL 陣列。 是 options 可用來自訂瀏覽器下載活動外觀的物件。
欲了解更多函式資訊, fetch 請參閱 BackgroundFetchManager.fetch () 。
使用 App Badging API 和通知 API 來重新吸引用戶
使用 App Badging API 和通知 API,讓使用者知道背景任務、下載或新內容已完成,且不會中斷工作流程。 使用徽章和通知可以提升用戶對應用程式的重新參與度。
在 Microsoft Edge 中,徽章會出現在工作列的應用程式圖示上,通知則整合到系統通知中心。
想了解如何使用這些 API,請參閱 Re-Engage 用戶的徽章、通知與推播訊息。