發布日期:2015 年 12 月 8 日
背景同步是網頁 API,可讓您延後執行動作,直到使用者連線穩定為止。這樣一來,您就能盡快支援使用者傳送任何檔案。
問題
網際網路是浪費時間的好地方。如果沒有在網路上浪費時間,我們就不會知道貓咪不喜歡花、變色龍喜歡泡泡,或是 Eric Bidelman 是90 年代末期的推桿高爾夫英雄。
但有時,我們只是不想浪費時間。理想的使用者體驗應如下:
- 手機從口袋中掉出來。
- 達成次要目標。
- 手機放回口袋。
- 恢復生活。
但連線品質不佳時,這項體驗往往會受到影響。我們都很有感。你盯著空白畫面或旋轉圖示,明明知道應該放棄並繼續生活,但你還是再等了 10 秒,以防萬一。10 秒後呢?不會發生任何事情。
但為什麼要放棄?你已經投入時間,如果一無所獲就離開,實在太浪費了,因此你繼續等待。此時你想放棄,但你知道只要再等一下,所有內容就會載入。
服務工作人員可讓您從快取提供內容,解決網頁載入問題。但如果網頁需要傳送內容至伺服器呢?
目前,使用者按下「傳送」後,必須盯著旋轉符號,直到訊息傳送完成為止。如果使用者嘗試離開或關閉分頁,我們會使用 onbeforeunload 顯示類似「不行,你還需要多看這個微調器。Sorry"。如果使用者沒有連線,我們會告知使用者「抱歉,你必須稍後再試一次」。
背景同步處理功能可協助你提升效率。
解決方法
以下影片展示了 Emojoy,這是僅限使用表情符號的即時通訊示範。這項工具是漸進式網頁應用程式,採用離線優先設計。應用程式會使用推播訊息和通知,並在背景同步處理。
如果使用者在沒有網路連線時嘗試傳送訊息,系統會在連上網路後於背景傳送訊息。
能夠在背景傳送資料,也能提升使用者感受到的效能。應用程式不需要如此重視訊息傳送作業,因此可以直接將訊息新增至輸出內容。
Chrome 49 以上版本支援背景同步處理。
如何要求背景同步
這項低階功能符合可擴充網頁的風格,可讓您自由執行所需操作。您要求在使用者連線時觸發事件,如果使用者已連線,則會立即觸發。接著,您會監聽該事件,並執行所需操作。
與推播訊息一樣,它會使用服務工作人員做為事件目標,因此即使網頁未開啟,也能正常運作。如要開始,請從頁面註冊同步:
// 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() 應傳回 Promise,指出嘗試執行的任何作業是否成功。如果 Promise 實現,表示同步處理完成。如果失敗,系統會排定時間重試。重試同步作業時,系統也會等待連線,並採用指數輪詢。
同步的標記名稱 (範例中的「myFirstSync」) 不得重複。如果使用與待處理同步相同的標記註冊同步,系統會與現有同步合併。也就是說,使用者每次傳送郵件時,您都可以註冊「清除寄件匣」同步作業,但如果使用者在離線時傳送 5 封郵件,他們上線時您只會收到一次同步作業。如要取得 5 個不同的同步事件,請使用不重複的標記。
請參閱這個示範,瞭解如何使用同步事件顯示通知。
背景同步處理的用途
在理想情況下,您會使用這項功能,安排傳送網頁生命週期以外的任何重要資料。即時通訊訊息、電子郵件、文件更新、設定變更、相片上傳,或任何您想傳送至伺服器的內容,即使使用者離開或關閉分頁也沒問題。網頁可能會將這些訊息儲存在 indexedDB 的「寄件匣」中,而 Service Worker 會擷取並傳送這些訊息。
不過,您也可以使用這項功能擷取少量資料。
離線維基百科試用版
這是我為「大幅提升網頁載入速度」建立的離線維基百科示範。我後來為這個應用程式加入了一些背景同步魔法。
請親自試試看:
- 請勿關閉這個瀏覽器分頁。
- 開啟飛航模式或關閉 Wi-Fi,即可離線使用。
- 按一下其他文章的連結。
- 系統應會告知您網頁載入失敗 (如果網頁只是需要一段時間才能載入,也會顯示這則訊息)。
- 同意接收通知。
- 關閉瀏覽器。
- 切換為線上狀態
- 文章下載並快取完畢後,您就會收到通知,可以開始閱讀!
使用這種模式時,使用者可以將手機放入口袋,繼續生活,因為手機會在擷取到所需內容時發出快訊。
權限
我展示的範例使用網頁通知,這需要權限,但背景同步本身不需要。
同步事件通常會在使用者開啟網站頁面時完成,因此要求使用者授權會導致體驗不佳。為防範濫用行為,我們限制了註冊及觸發同步作業的時間。例如:
- 只有在使用者開啟網站視窗時,您才能註冊同步事件。
- 事件執行時間設有上限,因此您無法使用事件每隔 x 秒 Ping 伺服器、挖礦比特幣等。
當然,這些限制可能會根據實際使用情況放寬或收緊。
漸進增強
在等待背景同步成為基準的同時,您可以將其做為漸進式強化功能:
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();
}
如果無法使用 Service Worker 或背景同步功能,請照常發布網頁內容。
即使使用者連線狀況良好,也建議使用背景同步功能,因為這樣可避免在傳送資料期間發生導覽和關閉分頁的情況。
未來
我們的目標是在 2016 年上半年,將背景同步處理功能發布至 Chrome 的穩定版,同時開發「定期背景同步處理」變體。透過定期背景同步,您可以要求受時間間隔、電池狀態和網路狀態限制的事件。當然,這需要使用者授權,而且這些事件的觸發時間和頻率也取決於瀏覽器。換句話說,新聞網站可以要求每小時同步一次,但瀏覽器可能會知道您只會在 07:00 閱讀該網站,因此系統會在每天 06:50 執行同步作業。這個想法比一次性同步處理更進一步,但我們即將推出這項功能。
我們會逐步將 Android 和 iOS 的成功模式帶到網路上,同時保留網路的優點!