共用方式為


在背景同步並更新 PWA

利用服務工作者,Progressive Web App (PWA) 可以在背景工作,即使使用者未使用該應用程式,也能提供更佳的離線體驗。

請考慮以下使用情境:

  • 一款電子郵件應用程式,讓使用者能隨時撰寫訊息並發送,即使離線也能使用。
  • 一個每天抓取新文章的新聞應用程式,讓使用者在打開應用程式時可以閱讀。
  • 一款讓使用者下載歌曲並離線聆聽的音樂應用程式。

這三種使用情境皆可透過以下 API 實現 PWA:

  • 背景同步 API
  • 週期性背景同步 API
  • 背景擷取 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 背景同步示範應用程式

使用示範版:

  1. 請在新視窗或分頁中進入 PWA 背景同步 API 示範

    安裝應用程式:

  2. 在地址欄中,點擊 可用應用程式。安裝 PWA 背景同步 API 示範 (應用程式 可用圖示) 按鈕。

    Edge會開啟 安裝PWA背景同步API示範 對話框。

  3. 點擊 安裝 按鈕。

    打開 了 PWA 檔案處理器的示範 應用程式視窗。 應用程式 安裝 對話框會打開。

  4. 點擊 允許 按鈕。

    PWA 背景同步 API 示範應用程式會在專用視窗中開啟。 Windows 應用程式 對話框會提示是否將應用程式釘選到工作列。

  5. 點擊 「是」 按鈕。

    使用連接網路的應用程式:

  6. 在已安裝的 PWA 背景同步 API 示範 應用程式中,在 留言 文字框輸入留言,例如 「Hello」,然後點擊 「發送 」按鈕。

    訊息已經發送。 您輸入的訊息顯示在 留言 文字框下方,初始狀態為 「發送中」,接著顯示「 已發送✅」狀態:

    在示範應用程式中輸入評論

    斷開網路:

  7. 在應用程式視窗中右鍵點擊,然後選擇 檢查

    DevTools 會以專用視窗開啟。

  8. 在 DevTools 中,選擇 Network (Network 圖示) 工具。

  9. 網路限速下拉選單中,選擇「離線」而不是「無限速」:

    DevTools 網路限速:離線

    網路 標籤會 新增一個警告圖示,提醒你有網路限速問題。

    使用應用程式,斷開網路連線:

  10. 在已安裝的 PWA 背景同步 API 示範 應用程式中,在 留言 文字框中輸入留言,例如 再次輸入 Hello,然後點擊 「發送 」按鈕。

    你輸入的訊息會出現,先顯示「發送中」,接著又顯示「失敗」。❌ 「 嘗試再發送 」按鈕會出現在訊息矩形內:

    嘗試再發送按鈕

  11. 點擊「 嘗試再發送 」按鈕。

    在訊息矩形內,狀態會變成 稍後再試🛜,且「 嘗試再發送 」按鈕也消失了:

    我之後會再試試看

    如果狀態仍是 失敗❌,你可以重置服務工人,讓狀態變成 「稍後嘗試」🛜 ,當適當時機:

    1. 在 DevTools 中,選擇 應用程式 (應用程式圖示) 工具。

    2. 在左側的導覽窗格中,選擇 服務人員,然後在右上角點選 取消註冊

    3. 在應用程式視窗中,右鍵點擊網頁,然後選擇 重新整理

    連接網路:

  12. 在專用的 DevTools 視窗裡,網路 限速 下拉選單,而不是 離線,而是選擇 「無限速」。

    網路 分頁 中的降速警告圖示已被移除。

    使用應用程式,重新連接網路:

  13. 切換到已安裝的 PWA 背景同步 API 示範 應用程式。

    顯示狀態為 已發送✅:

    寄件日期

  14. 可選擇性地,在網頁中右鍵點擊,然後選擇 重新整理

    訊息會被刪除。

除錯背景與 DevTools 同步

要測試背景同步程式碼,你不必先離線再上線,再等 Microsoft Edge 觸發 sync 事件。 相反地,DevTools 讓你模擬背景同步事件。

模擬事件 sync

  1. 開啟 DevTools (F12) 。
  2. 選擇 應用程式>服務工作者
  3. 同步 輸入欄位輸入你註冊同步時使用的標籤名稱。
  4. 選擇 同步 按鈕。

在應用程式面板中模擬背景同步

你也可以在 DevTools 中記錄應用程式產生的背景同步活動,具體如下:

  1. 開啟 DevTools (F12) 。
  2. 選擇 應用程式>背景同步
  3. 選擇 開始記錄事件

同步註冊與派遣顯示在事件日誌表中:

日誌背景同步事件

使用 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 的更多資訊,請參見:

示範應用程式:DevTools 技巧

DevTools Tips 是一個使用 Periodic Background Sync API 的 PWA。 [DevTools Tips] PWA 每天擷取新的開發者工具提示並存入快取,讓使用者下次開啟應用程式時,無論是否在線都能存取。

DevTools 技巧應用程式

GitHub 查看原始碼。 特別是,應用程式會在 registerPeriodicSync 函式中登錄週期同步。 服務人員代碼是應用程式監periodicsync聽事件的地方。

除錯定期背景同步與 DevTools

你可以用 DevTools 模擬 periodicsync 事件,而不是等到最短的間隔。

模擬事件:

  1. 開啟 DevTools (F12) 。
  2. 選擇 應用程式>服務工作者
  3. 在週期 同步 輸入欄位輸入你註冊週期同步時使用的標籤名稱。
  4. 選擇 週期性同步 按鈕。

在應用程式面板中模擬週期性的背景同步

你也可以在 DevTools 中記錄應用程式產生的週期性背景同步活動:

  1. 開啟 DevTools (F12) 。
  2. 選擇 應用程式>週期性背景同步
  3. 選擇 開始記錄事件

週期性同步註冊與派遣會出現在事件日誌表中。

記錄週期性背景同步事件

當應用程式或服務工作者未執行時,使用背景擷取 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 用戶的徽章、通知與推播訊息