大家好,很高興又見面了,我是"進階前端進階",由我帶着大家一起關注前端前沿、深入前端底層技術,大家一起進步,也歡迎大家關注、點贊、收藏、轉發!
Background Fetch簡稱bgFetch。
1.為什麼是Background Fetch?
深入了解浏覽器Background Fetch。 Created by Decipher Zone Softwares
1.1 為什麼要Background Fetch?
當 Web 應用程式需要下載下傳大檔案時,例如電影、音頻檔案和軟體,通常可能會出現問題,因為使用者需要保持與頁面的連接配接才能完成下載下傳。 如失去連接配接,關閉頁籤等任務将停止。
為什麼要Background Fetch?From:istockphoto
Background Synchronization 為 service workers 提供了一種延遲處理直到使用者連接配接的方法。但是不能用于長時間運作的任務,例如下載下傳大檔案。 同時,要求 service worker 在完成之前保持活動狀态,因為為了節省電池壽命、防止在背景發生不需要的任務,浏覽器将在某個時候終止任務。
1.2 Background Fetch解決了什麼痛點?
Background Fetch API 解決了這個問題。 它為 Web 開發人員建立了一種方式,讓浏覽器在背景執行一些操作,例如,當使用者單擊按鈕下載下傳視訊檔案時。 然後浏覽器以使用者可見的方式執行提取,顯示進度、提供取消下載下傳的方法。 下載下傳完成後,浏覽器會打開 Service Worker,此時應用程式可以根據需要對響應執行某些操作。
如果使用者在離線時啟動程序,背景提取 API 将啟用提取。 一旦連接配接起來,它就會開始。 如果使用者下線,該過程将暫停,直到使用者再次上線。
2.Background Fetch如何工作?
Background Fetch工作流程如下:
- 告訴浏覽器在背景執行一組fetch。
- 浏覽器調用fetch,向使用者顯示進度。
- 一旦擷取完成或失敗,浏覽器就會打開service workers并觸發一個事件來告訴你發生了什麼,由開發者決定如何處理響應。
如果使用者在第 1 步後關閉了站點的頁面,下載下傳将繼續。
fetch是高度可見的并且很容易中止,是以不存在太長的背景同步任務的隐私問題。 而且service worker 也不會持續運作,是以不用擔心濫用系統,例如在背景挖礦。
在某些平台(例如 Android)上,浏覽器可能會在第 1 步後關閉,因為浏覽器可以将fetch操作交給作業系統。如果使用者在離線時開始下載下傳,或者在下載下傳過程中離線,背景fetch将暫停并稍後恢複。
3.浏覽器相容
3.1 特征檢測
與任何新功能一樣,需要檢測浏覽器是否支援它。 對于 Background Fetch,可以通過如下代碼快速檢測:
if ('BackgroundFetchManager' in self) {
//浏覽器支援Background Fetch!
}
從caniuse的資料來看,該API的浏覽器整體支援率達到了73.58%。Chrome從74版本開始,Edge從79版本開始都已經支援Background Fetch。不過,可惜的是,FireFox和Safari目前支援并不好。
3.2 執行個體化Background Fetch
使用 Background Fetch 需要注冊一個 service worker。 然後調用 backgroundFetch.fetch() 來執行,同時傳回一個Promise。
Background Fetch提取可能會請求多個檔案。 在下面的示例中,請求了 MP3 和 JPEG。
navigator.serviceWorker.ready.then(async (swReg) => {
const bgFetch = await swReg.backgroundFetch.fetch(
// service worker的fetch方法
"my-fetch",
["/ep-5.mp3", "ep-5-artwork.jpg"],
// 請求MP3和JPEG
{
title: "Episode 5: Interesting things.",
icons: [
{
sizes: "300x300",
src: "/ep-5-icon.png",
type: "image/png",
},
],
downloadTotal: 60 * 1024 * 1024,
}
);
});
3.3 擷取已有的Background Fetch
navigator.serviceWorker.ready.then(async (swReg) => {
const bgFetch = await swReg.backgroundFetch.get('my-fetch');
});
通過傳遞Background Fetch的id來擷取, 如果沒有使用該 ID 的Background Fetch,則傳回 undefined。
Background Fetch從它被注冊的那一刻起就被認為是“活躍的”,直到它成功、失敗或被終止。可以使用 getIds 擷取所有活動Background Fetch的清單:
navigator.serviceWorker.ready.then(async (swReg) => {
const ids = await swReg.backgroundFetch.getIds();
});
3.4 跟蹤Background Fetch進度
可以通過進度事件來完成。請記住,downloadTotal可以是任何值,未提供,則為 0。
bgFetch.addEventListener('progress', () => {
// If we didn't provide a total, we can't provide a %.
if (!bgFetch.downloadTotal) return;
const percent = Math.round(bgFetch.downloaded / bgFetch.downloadTotal * 100);
console.log(`Download progress: ${percent}%`);
});
3.5 擷取請求和響應
bgFetch.match('/ep-5.mp3').then(async (record) => {
if (!record) {
console.log('No record found');
return;
}
console.log(`Here's the request`, record.request);
const response = await record.responseReady;
console.log(`And here's the response`, response);
});
在 Chrome 目前的實作中,您隻能在 backgroundfetchsuccess、backgroundfetchfailure 和 backgroundfetchabort service worker 事件期間擷取請求和響應(見下文)
4.本文總結
本文主要和大家介紹浏覽器的新特性Background Fetch,因為Background Fetch本身的複雜性,文章沒有過多的展開。但是文末的參考資料提供了大量優秀文檔以供學習,如果有興趣可以自行閱讀。如果大家有什麼疑問歡迎在評論區留言。
參考資料
https://developer.mozilla.org/en-US/docs/Web/API/Background_Fetch_API
https://caniuse.com/?search=Background%20Fetch
https://developer.chrome.com/blog/background-fetch/