透過 Periodic Background Sync API 獲得更豐富的離線體驗

在背景同步網頁應用程式的資料,打造更貼近應用程式的體驗

Joe Medley
Joe Medley

您是否曾經歷下列任一情況?

  • 搭乘火車或地鐵時,網路連線不穩定或完全中斷
  • 觀看過多影片後,電信業者限制了你的網路用量
  • 居住在頻寬難以滿足需求的國家/地區

如果您有過這種經驗,那麼您一定會覺得在網路上完成某些事情很麻煩,並想知道為什麼在這些情況下,專屬平台的應用程式經常表現得更好。特定平台的應用程式可以提前擷取最新內容,例如新聞文章或天氣資訊。即使在捷運上沒有網路,您還是可以閱讀新聞。

定期在背景同步處理功能可讓網頁應用程式定期在背景同步處理資料,讓網頁應用程式更接近特定平台應用程式的行為。

立即試用

您可以使用實際示範應用程式,嘗試定期背景同步處理。使用前,請確認:

  • 你使用的是 Chrome 80 以上版本。
  • 請先安裝網頁應用程式,再啟用定期背景同步處理功能。

概念和用法

定期背景同步功能可讓您在啟動漸進式網頁應用程式或服務工作者支援的頁面時,顯示最新內容。這項功能會在您未使用應用程式或網頁時,在背景下載資料。這可避免應用程式在啟動後,在觀看內容時重新整理內容。更棒的是,這麼做可避免應用程式在重新整理前顯示內容旋轉圖示。

如果沒有定期的背景同步功能,網頁應用程式就必須使用其他方法下載資料。常見的例子是使用推播通知喚醒服務 worker。使用者會因「有新資料可用」等訊息而中斷操作。更新資料本質上是一種副作用。您仍可選擇使用推播通知,接收重要更新內容,例如重大的即時新聞。

定期在背景同步處理功能很容易與背景同步處理功能混淆。雖然名稱相似,但用途不同。除了其他用途外,背景同步處理功能最常用於在先前要求失敗時,將資料重新傳送至伺服器。

提高使用者參與度

如果執行不當,定期的背景同步作業可能會浪費使用者的資源。在發布前,Chrome 會先進行試用期,確保一切正常。本節將說明 Chrome 為盡可能提供實用的功能,所做出的部分設計決策。

Chrome 做出的第一個設計決策是,網頁應用程式必須在使用者在裝置上安裝應用程式,並以獨立應用程式形式啟動後,才能使用定期背景同步處理功能。在 Chrome 的一般分頁中,無法使用定期在背景同步處理功能。

此外,Chrome 不希望未使用的或很少使用的網頁應用程式浪費電池或資料,因此設計了定期背景同步功能,讓開發人員必須透過為使用者提供價值來取得這項功能。具體來說,Chrome 會使用網站參與度分數 (about://site-engagement/) 判斷是否可針對特定網頁應用程式執行定期背景同步作業,以及執行頻率。換句話說,除非參與度分數大於零,否則系統不會觸發 periodicsync 事件,且分數值會影響 periodicsync 事件觸發的頻率。這樣一來,只有您正在使用的應用程式會在背景同步。

定期背景同步處理與熱門平台上的現有 API 和做法有幾分相似之處。舉例來說,使用者關閉網頁後,一次性背景同步作業和推播通知可讓網頁應用程式邏輯透過服務工作者持續運作一段時間。在大多數平台上,使用者安裝的應用程式通常會在背景定期存取網路,以便提供更優質的使用者體驗,例如提供重要更新、預先擷取內容、同步處理資料等。同樣地,定期背景同步也會延長網頁應用程式邏輯的生命週期,以便定期執行,每次執行時間可能為幾分鐘。

如果瀏覽器允許這種情況經常發生且沒有限制,可能會導致某些隱私權問題。以下是 Chrome 針對定期背景同步處理的風險採取的措施:

  • 背景同步處理活動只會在裝置先前連線的網路上發生。Chrome 建議您只連線至可靠的一方所經營的網路。
  • 如同所有網際網路通訊,定期背景同步處理會顯示客戶端的 IP 位址、與其通訊的伺服器,以及伺服器名稱。為了減少這類曝光,瀏覽器會限制應用程式的背景同步作業頻率,以符合使用者使用該應用程式的頻率。如果使用者停止經常與應用程式互動,定期背景同步作業就會停止觸發。這項功能是針對特定平台應用程式的現況,帶來了淨改善。

何時可以使用?

使用規則會因瀏覽器而異。總結上述內容,Chrome 對定期在背景同步處理的規定如下:

  • 特定使用者參與度分數。
  • 是否曾使用過網路。

開發人員無法控制同步處理的時間。同步處理頻率會與應用程式的使用頻率一致。(請注意,目前平台專屬應用程式不會執行這項操作)。也會考量裝置的電源和連線狀態。

何時應使用?

當服務工作者喚醒來處理 periodicsync 事件時,您有機會可以要求資料,但沒有義務這麼做。處理事件時,您應考量網路狀況和可用的儲存空間,並下載不同數量的資料做為回應。您可以參考下列資源:

權限

安裝服務工作者後,請使用 Permissions API 查詢 periodic-background-sync。您可以透過視窗或服務工作者背景執行這項操作。

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.
}

註冊定期同步處理

如先前所述,定期在背景同步處理功能需要服務工作程。使用 ServiceWorkerRegistration.periodicSync 擷取 PeriodicSyncManager,然後對其呼叫 register()。註冊時必須提供標記和最小同步處理間隔 (minInterval)。標記可識別註冊的同步處理作業,以便註冊多個同步處理作業。在下方範例中,標記名稱為 'content-sync'minInterval 為一天。

const registration = await navigator.serviceWorker.ready;
if ('periodicSync' in registration) {
  try {
    await registration.periodicSync.register('content-sync', {
      // An interval of one day.
      minInterval: 24 * 60 * 60 * 1000,
    });
  } catch (error) {
    // Periodic background sync cannot be used.
  }
}

驗證註冊

呼叫 periodicSync.getTags() 即可擷取註冊標記陣列。以下範例使用標記名稱確認快取更新功能是否處於啟用狀態,以免再次更新。

const registration = await navigator.serviceWorker.ready;
if ('periodicSync' in registration) {
  const tags = await registration.periodicSync.getTags();
  // Only update content if sync isn't set up.
  if (!tags.includes('content-sync')) {
    updateContentOnPageLoad();
  }
} else {
  // If periodic background sync isn't supported, always update.
  updateContentOnPageLoad();
}

您也可以使用 getTags(),在網頁應用程式的設定頁面中顯示有效註冊清單,讓使用者啟用或停用特定類型的更新。

回應定期背景同步事件

如要回應定期背景同步處理事件,請將 periodicsync 事件處理常式新增至服務工作者。傳遞至該物件的 event 物件會包含 tag 參數,該參數與註冊期間使用的值相符。舉例來說,如果定期背景同步作業以 'content-sync' 的名稱註冊,則 event.tag 會是 'content-sync'

self.addEventListener('periodicsync', (event) => {
  if (event.tag === 'content-sync') {
    // See the "Think before you sync" section for
    // checks you could perform before syncing.
    event.waitUntil(syncContent());
  }
  // Other logic for different tags as needed.
});

取消註冊同步處理

如要結束已註冊的同步處理作業,請呼叫 periodicSync.unregister(),並使用要取消註冊的同步處理作業名稱。

const registration = await navigator.serviceWorker.ready;
if ('periodicSync' in registration) {
  await registration.periodicSync.unregister('content-sync');
}

介面

以下簡要說明 Periodic Background Sync API 提供的介面。

  • PeriodicSyncEvent:在瀏覽器選擇的時間傳遞至 ServiceWorkerGlobalScope.onperiodicsync 事件處理常式。
  • PeriodicSyncManager。註冊及取消註冊定期同步處理作業,並為已註冊的同步處理作業提供標記。從 ServiceWorkerRegistration.periodicSync` 屬性擷取此類別的例項。
  • ServiceWorkerGlobalScope.onperiodicsync:註冊處理常式,以便接收 PeriodicSyncEvent
  • ServiceWorkerRegistration.periodicSync:傳回 PeriodicSyncManager 的參照。

範例

更新內容

以下範例會使用定期背景同步處理功能,下載並快取新聞網站或網誌的最新文章。請注意標記名稱,這會指出這是哪種類型的同步作業 ('update-articles')。對 updateArticles() 的呼叫會在 event.waitUntil() 中包裝,因此服務工作者不會在文章下載及儲存前終止。

async function updateArticles() {
  const articlesCache = await caches.open('articles');
  await articlesCache.add('/api/articles');
}

self.addEventListener('periodicsync', (event) => {
  if (event.tag === 'update-articles') {
    event.waitUntil(updateArticles());
  }
});

在現有網頁應用程式中新增定期在背景同步處理功能

這組變更是為了在現有 PWA 中新增定期背景同步功能。這個範例包含多個實用的記錄陳述式,可說明網路應用程式中週期性背景同步作業的狀態。

偵錯

在本機測試時,要取得及檢視定期背景同步作業的端對端資料可能會相當困難。在偵錯網頁應用程式行為時,關於有效註冊、大致同步間隔和過去同步事件的記錄等資訊,可提供寶貴的背景資訊。幸好,您可以透過 Chrome 開發人員工具中的實驗功能找到所有這類資訊。

錄製本機活動

開發人員工具的「定期背景同步處理」部分會根據定期背景同步處理生命週期中的關鍵事件進行排序,這些事件包括註冊同步處理、執行背景同步處理和取消註冊。如要取得這些事件的相關資訊,請按一下「開始錄製」

開發人員工具中的錄影按鈕
開發人員工具中的錄製按鈕

在錄製期間,DevTools 會顯示與事件相對應的項目,並為每個項目記錄上下文和中繼資料。

記錄的定期背景同步處理資料範例
已記錄的定期在背景同步處理資料範例

啟用錄製功能一次後,系統最多會保留三天,讓開發人員工具擷取背景同步作業的本機偵錯資訊,即使是幾小時後的資訊也沒問題。

模擬事件

雖然記錄背景活動很有幫助,但有時您可能會想立即測試 periodicsync 處理常式,而不需要等待事件以正常節奏觸發。

您可以透過 Chrome 開發人員工具「應用程式」面板中的「Service Workers」部分執行這項操作。您可以使用「定期同步處理」欄位,為事件提供要使用的標記,並觸發事件的次數不限。

「Application」面板的「Service Workers」部分會顯示「Periodic Sync」文字欄位和按鈕。

使用 DevTools 介面

自 Chrome 81 版起,您會在開發人員工具的「應用程式」面板中看到「定期背景同步」部分。

「應用程式」面板顯示「定期在背景同步處理」專區