共用方式為


在背景同步並更新 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 文件

示範應用程式

My Movie List PWA 是一款示範應用程式,利用背景同步 API 在使用者離線時稍後擷取電影資訊。

我的電影清單 PWA 示範應用程式

要測試背景同步:

  1. 安裝應用程式。

  2. 使用搜尋輸入欄位搜尋電影。

  3. 離線。 要做到這點,請打開 DevTools (F12) ,然後選擇 「應用程式>服務工作者>離線 」的勾選框。

    用 DevTools 模擬離線狀態

  4. 在其中一個影片結果中,選擇 更多資訊

  5. 應用程式會跳出訊息通知你離線,電影資訊稍後會自動被取回。

    離線訊息

  6. 上網看看。 要做到這點,在 DevTools 中,請清除 應用程式>服務工作者>離線 的勾選框。

  7. 重新載入應用程式。 電影細節現在已經公布。

想看範例程式碼,可以參考 movies-db-pwa 倉庫。

除錯背景與 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 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 用戶的徽章、通知與推播訊息