Service Worker

使用者希望應用程式在網路連線速度緩慢或不穩定時,或甚至離線時,可以穩定啟動。使用者會預期最近互動的內容 (例如媒體曲目、票券及行程) 並可供使用。當系統無法執行要求時,他們會希望應用程式能夠通知他們,而不會發生失敗或停止運作的情形。而且他們希望這一切都能迅速達成。如毫秒之可造就數百萬人,即使載入時間縮短 0.1 秒,轉換率最多可提升 10%。Service Worker 是一項工具,可讓您的漸進式網頁應用程式 (PWA) 滿足使用者期待。

可做為中介軟體 Proxy,在 PWA 和伺服器 (包括自有伺服器和跨網域伺服器) 之間在裝置端運作的 Service Worker。
Service Worker 就像 PWA 及其互動伺服器之間的中介軟體。

當應用程式要求的服務工作站範圍涵蓋的資源時,Service worker 會攔截該要求,並做為網路 Proxy 使用 (即便使用者離線)。然後判斷是否應使用 Cache Storage API 從快取提供資源、從網路提供資源,就像在沒有使用中的 Service Worker 一樣,也能透過本機演算法建立資源。如此一來,即使應用程式處於離線狀態,也能提供優質體驗,例如平台應用程式。

註冊 Service Worker

Service Worker 必須先為您的 PWA 註冊 PWA,您才能控制網頁。這表示使用者首次開啟 PWA 時,所有網路要求都會直接傳送至您的伺服器,因為服務工作站尚未控制您的網頁。

檢查瀏覽器是否支援 Service Worker API 後,PWA 就能註冊 Service Worker。載入完畢後,Service Worker 會自行設定 PWA 和網路之間,藉此攔截要求並提供對應的回應。

if ('serviceWorker' in navigator) {
   navigator.serviceWorker.register("/serviceworker.js");
}
嘗試註冊 Service Worker,看看瀏覽器的開發人員工具會有什麼變化。

確認 Service Worker 是否已註冊

如要確認服務工作站是否已註冊,請在慣用的瀏覽器中使用開發人員工具。

若是以 Firefox 和 Chromium 為基礎的瀏覽器 (Microsoft Edge、Google Chrome 或 Samsung Internet):

  1. 開啟開發人員工具,然後按一下「Application」分頁標籤。
  2. 選取左側窗格中的「Service Workers」
  3. 檢查服務工作站的指令碼網址是否顯示「已啟用」狀態。(詳情請參閱「生命週期」一文)。在 Firefox 中,狀態可以是「執行中」或「已停止」。

在 Safari 中:

  1. 按一下「Develop」(開發) >「Service Workers」(服務工作站)
  2. 請透過這個選單尋找包含目前來源的項目。按一下該項目即可在 Service Worker 的內容中開啟檢查器。
Chrome、Firefox 和 Safari 上的 Service Worker 開發人員工具。
Chrome、Firefox 和 Safari 上的 Service Worker 開發人員工具。

內容範圍

服務工作處理程序所在的資料夾會決定其範圍。位於 example.com/my-pwa/sw.js 的 Service Worker 可以控制 my-pwa 路徑 (例如 example.com/my-pwa/demos/) 中或底下的任何導覽。服務工作站只能控管自身範圍內的項目 (頁面、工作站、統稱「用戶端」)。此範圍適用於瀏覽器分頁和 PWA 視窗,

每個範圍只允許一個 Service Worker。當 Service Worker 啟用中後,無論記憶體中有多少用戶端 (PWA 視窗或瀏覽器分頁),通常只有一個執行個體。

Safari 的範圍管理 (稱為分區) 較為複雜,影響範圍與跨網域 iframe 搭配運作的方式。如要進一步瞭解 WebKit 的實作方式,請參閱網誌文章

生命週期

服務工作站的生命週期會指出其安裝方式,與 PWA 安裝方式不同。

服務工作站生命週期的從註冊 Service Worker 開始。接著,瀏覽器會嘗試下載並剖析 Service Worker 檔案。如果剖析成功,系統會觸發服務工作站的 install 事件。install 事件只會觸發一次。

Service Worker 會在沒有使用者授權的情況下自動安裝,即使使用者未安裝 PWA 也一樣。Service Worker API 也可使用,即使平台不支援 PWA 安裝功能 (例如電腦裝置上的 Safari 和 Firefox) 也一樣。

安裝完成後,服務工作站必須先啟用才能控制用戶端 (包括 PWA)。Service Worker 準備好控管用戶端時,就會觸發 activate 事件。不過根據預設,啟用的服務工作站會無法在您下次透過重新載入頁面或重新開啟 PWA 的方式前往該頁面時,管理已註冊該頁面的網頁。

您可以使用 self 物件監聽 Service Worker 全域範圍內的事件:

serviceworker.js

// This code executes in its own worker or thread
self.addEventListener("install", event => {
   console.log("Service worker installed");
});
self.addEventListener("activate", event => {
   console.log("Service worker activated");
});

更新 Service Worker

當瀏覽器偵測到控制用戶端的 Service Worker 控制用戶端,以及來自伺服器的新版 Service Worker 檔案版本不同,服務工作站便會更新。

成功安裝後,新的服務工作站會等到啟用再啟用,直到舊的服務工作站不再控制任何用戶端為止。這個狀態稱為「等待中」,瀏覽器可以確保一次只會執行一個版本的 Service Worker。

重新整理頁面或重新開啟 PWA 無法控制新的 Service Worker。使用者必須使用目前的 Service Worker 關閉或離開所有分頁和視窗,然後再返回,為新的 Service Worker 控制項提供控制選項。詳情請參閱「Service Worker 生命週期」。

Service Worker 壽命

已安裝和已註冊的 Service Worker 可管理範圍內的所有網路要求。這項服務會在自身的執行緒上執行,且由瀏覽器控制啟用和終止,因此可在 PWA 開啟前或關閉後運作。服務工作站會在自己的執行緒上執行,但記憶體內狀態可能不會持續存在服務工作站執行作業,因此請確定每次執行時要重複使用的內容都可以在 IndexedDB 或其他永久儲存空間中找到。

如果服務工作站尚未執行,每當有網路要求在範圍內傳送網路要求,或收到定期背景同步處理或推送訊息等觸發事件時,服務工作站就會啟動。

如果服務工作站已閒置幾秒鐘,或長時間處於忙碌狀態,就會終止服務工作站。這個時間長度依瀏覽器而異。如果 Service Worker 已終止,且發生會啟動該事件的事件,則會重新啟動。

功能

已註冊且正在運作的 Service Worker 所使用的執行緒與 PWA 主執行緒完全不同。不過根據預設,Service Worker 檔案本身沒有任何行為。它不會快取或提供任何資源,這些是程式碼需要執行的操作。請參閱以下章節。

服務工作站的功能不只是用於 Proxy 或提供 HTTP 要求。系統會額外提供其他功能,如背景程式碼執行、網路推播通知與處理付款等其他用途。我們會在「功能」中討論這些新增項目。

資源