背景同步簡介

Jake Archibald
Jake Archibald

背景同步處理是新的網路 API,可讓您在使用者連線穩定前,暫緩執行動作。這可確保使用者要傳送的內容確實傳送出去。

問題

網際網路是消磨時間的好地方,我們不會浪費時間在網路上搜尋,貓咪不喜歡花朵變色龍喜歡泡泡,或是Eric Bidelman90 年代末的推桿高爾夫英雄

但有時,我們不想浪費時間。理想的使用者體驗應類似於:

  1. 手機不在身邊,也能輕鬆使用。
  2. 達成小目標。
  3. 手機放回口袋。
  4. 繼續生活。

不幸的是,這項體驗經常因連線不佳而中斷。我們都曾經歷過這種情況。你盯著空白畫面或旋轉圖示,知道應該放棄並繼續生活,但還是再等 10 秒,以防萬一。10 秒後?不會發生任何事情。

但為何要放棄?你已經花費時間,如果什麼都沒有就離開,那就太浪費了,因此你決定繼續等待。到這個時候,你「想」放棄,但你知道,只要你放棄,一切就會回到原點,因為如果只是等待,所有內容都會載入。

服務工作處理程序可讓您從快取提供內容,藉此解決網頁載入的部分。但如果網頁需要傳送內容給伺服器,該怎麼辦呢?

目前,如果使用者按下訊息的「傳送」按鈕,就必須一直盯著旋轉圖示,直到傳送作業完成為止。如果他們嘗試離開或關閉分頁,我們會使用 onbeforeunload 顯示以下訊息:「不對,請你再看一下這個旋轉圖示。抱歉」;如果使用者沒有連線,我們會告訴使用者:「很抱歉,必須稍後再試一次。」

這根本是胡說八道。背景同步處理功能可讓你事半功倍。

解決方案

以下影片展示 Emojoy,這是一款僅限表情符號的聊天室示範。這是一個漸進式網頁應用程式,採用離線優先的運作方式。應用程式會使用推播訊息和通知,並使用背景同步功能。

如果使用者嘗試在沒有網路連線的情況下嘗試傳送訊息,那麼郵件會在一恢復連線後於背景傳送,可惜的是。

自 2016 年 3 月起,Chrome 49 以上版本提供背景同步處理功能。如要查看實際運作情形,請按照下列步驟操作:

  1. 開啟 Emojoy
  2. 處於離線狀態 (使用飛航模式或造訪當地的 Faraday 電路)。
  3. 輸入訊息。
  4. 返回主畫面 (視需要關閉分頁或瀏覽器)。
  5. 連上網路。
  6. 訊息會在背景傳送!

這樣一來,您就能在背景傳送資料,進而提升效能。應用程式不需要特別處理訊息傳送作業,因此可以立即將訊息加入輸出內容。

如何要求背景同步處理

以真正的可擴充網頁樣式來說,這是低階功能,可讓您自由執行所需操作。您會要求在使用者連線時觸發事件。如果使用者已連線,事件就會立即生效。接著,您可以監聽該事件,並執行所需的操作。

與推播訊息一樣,這項功能會使用 Service Worker 做為事件目標,讓這項功能在網頁未開啟時運作。如要開始,請透過網頁註冊同步處理:

// Register your service worker:
navigator.serviceWorker.register('/sw.js');

// Then later, request a one-off sync:
navigator.serviceWorker.ready.then(function(swRegistration) {
  return swRegistration.sync.register('myFirstSync');
});
 ```

Then listen for the event in `/sw.js`:

```js
self.addEventListener('sync', function(event) {
  if (event.tag == 'myFirstSync') {
    event.waitUntil(doSomeStuff());
  }
});

大功告成!在上述情況中,doSomeStuff() 應傳回承諾,指出嘗試執行的動作是否成功/失敗。如果傳回承諾,表示同步處理已完成。如果失敗,系統會安排另一次同步作業,以便重試。重試同步作業也會等待連線,並採用指數輪詢。

同步作業的標記名稱 (上例中的「myFirstSync」) 在特定同步作業中不得重複。如果您註冊同步處理時使用了與待處理的同步處理作業相同的代碼,則該代碼會與現有的同步作業合併。也就是說,您可以為每次使用者傳送郵件註冊「清空收件匣」同步作業,但如果使用者在離線時傳送 5 封郵件,您只會在他們上線時收到一次同步作業。如要 5 個獨立的同步處理事件,請使用專屬代碼!

這個簡單示範是以最低標準來說,這個示範就是使用同步處理事件來顯示通知。

我可以將背景同步處理功能用於哪些用途?

理想情況下,您應使用這項功能,安排在網頁生命週期結束後傳送您重視的任何資料。即時通訊訊息、電子郵件、文件更新、設定變更、相片上傳... 所有您想傳送至伺服器的內容 (即便使用者離開或關閉分頁)。網頁可能會將這些屬性儲存在已建立索引的資料庫中的「寄件匣」存放區,服務工作處理程序就會擷取這些項目,然後加以傳送。

不過,您也可以使用它擷取少量資料...

另一個示範!

這是我為超級充電網頁載入建立的離線維基百科示範。後來我已對這項功能增添一點背景同步特效。

你自己試試看請確認你使用的是 Chrome 49 以上版本,然後執行下列操作:

  1. 前往任一文章 (可能是 Chrome)。
  2. 處於離線狀態 (使用飛航模式,或是加入像我一樣可靠的行動服務供應商)。
  3. 按一下其他文章的連結。
  4. 您應該已經收到無法載入網頁的通知;如果網頁只載入一段時間,也會出現。
  5. 同意接收通知。
  6. 關閉瀏覽器。
  7. 切換為線上狀態
  8. 系統會在文章下載完畢、快取完成且可供查看時通知你!

使用者只要採用這個模式,就能將手機放入口袋,繼續過著自己的生活,因為他們知道手機會在擷取所需內容時發出通知。

權限

我展示的示範使用網頁通知,但需要取得權限,但背景同步處理則不會。

同步處理事件通常會在使用者開啟網站頁面時完成,因此要求使用者授權會導致使用者體驗不佳。我們會限制同步作業的註冊和觸發時間,以防濫用。例如:

  • 只有在使用者開啟網站視窗時,您才能註冊同步處理事件。
  • 事件執行時間設有上限,因此您無法使用它每隔 x 秒就對伺服器進行連線偵測 (ping)、比特幣等形式的連線偵測 (ping)。

當然,這些限制可能會根據實際使用情況而放寬或收緊。

漸進增強

所有瀏覽器均不支援背景同步功能,特別是 Safari 和 Edge 尚未支援 Service Worker。但漸進式增強功能能帶來以下好處:

if ('serviceWorker' in navigator && 'SyncManager' in window) {
  navigator.serviceWorker.ready.then(function(reg) {
    return reg.sync.register('tag-name');
  }).catch(function() {
    // system was unable to register for a sync,
    // this could be an OS-level restriction
    postDataFromThePage();
  });
} else {
  // serviceworker/sync not supported
  postDataFromThePage();
}

如果無法使用服務工作處理程序或背景同步處理功能,請直接在網頁上發布內容。

即便使用者看來連線狀況良好,也建議您使用背景同步功能。這樣一來,即使在資料傳送過程中,使用者遇到瀏覽及關閉分頁的情形,也還是能使用背景同步處理功能。

未來

我們預計在 2016 上半年將背景同步功能納入穩定版 Chrome,同時開發「定期背景同步」的變化版本。透過定期背景同步處理功能,您可以要求以時間間隔、電池狀態和網路狀態為限制的事件。當然,這需要使用者授權,且瀏覽器也會決定這些事件的觸發時機和頻率。換句話說,新聞網站可以要求每小時同步處理一次,但瀏覽器可能知道您只會在 7 點閱讀該網站,因此會在每天 6 點 50 分啟動同步處理作業。這個想法比一次性同步處理更為複雜,但我們會推出這項功能。

我們會逐步將 Android 和 iOS 的成功模式導入網頁,同時保留網頁的優點!