Service Worker

使用者希望應用程式在網路連線緩慢或不穩定的情況下,甚至離線時都能順利啟動。他們希望最近互動的內容 (例如媒體曲目、票券和行程) 都能使用。如果無法完成要求,使用者希望應用程式能告知他們,而不是無聲無息地失敗或當機。而且希望一切都能快速完成。如您在「毫秒造就百萬商機」一文中瞭解到的,載入時間只要縮短 0.1 秒,轉換率就能提高最多 10%。服務工作人員是讓漸進式網頁應用程式 (PWA) 滿足使用者期望的工具。

服務工作人員是中介軟體 Proxy,會在裝置端執行,介於 PWA 和伺服器之間,包括您自己的伺服器和跨網域伺服器。
服務工作人員是 PWA 與互動伺服器之間的中介軟體。

當應用程式要求服務工作站範圍涵蓋的資源時,服務工作站會攔截要求並充當網路 Proxy,即使使用者處於離線狀態也一樣。然後,它可以決定是否要使用 Cache Storage API 從快取提供資源、從網路提供資源 (就像沒有作用中的 Service Worker 一樣),或是從本機演算法建立資源。即使應用程式離線,您也能提供與平台應用程式一樣優質的體驗。

註冊 Service Worker

Service Worker 必須先註冊 PWA,才能控管網頁。也就是說,使用者第一次開啟 PWA 時,所有網路要求都會直接傳送至伺服器,因為 Service Worker 尚未控管網頁。

檢查瀏覽器是否支援 Service Worker API 後,PWA 即可註冊 Service Worker。載入後,服務工作人員會在 PWA 和網路之間設定自身,攔截要求並提供相應的回應。

if ('serviceWorker' in navigator) {
   navigator.serviceWorker.register("/serviceworker.js");
}

確認是否已註冊 Service Worker

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

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

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

使用 Safari:

  1. 依序點選「開發」>「服務工作人員」
  2. 請檢查這個選單,找出目前來源的項目。按一下該項目,即可開啟服務工作人員環境的檢查器。
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 視窗。

每個範圍只能有一個服務工作人員。服務工作人員處於啟用並執行狀態時,無論記憶體中有多少用戶端 (PWA 視窗或瀏覽器分頁),通常都只有一個例項可用。

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

生命週期

服務工作站有自己的生命週期,可決定服務工作站的安裝方式,與 PWA 安裝程序分開。

服務工作人員生命週期的起點是註冊服務工作人員。瀏覽器接著會嘗試下載及剖析服務工作人員檔案。如果剖析成功,系統會觸發服務工作人員的 install 事件。install事件只會觸發一次。

即使使用者未安裝 PWA,服務工作人員也會在使用者不知情的情況下安裝,不需要使用者授權。即使在不支援安裝 PWA 的平台 (例如桌機上的 Safari 和 Firefox),Service Worker API 仍可使用。

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

您可以使用 self 物件,在服務工作人員的全域範圍中監聽事件:

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 可以管理範圍內的所有網路要求。這項服務會在自己的執行緒上執行,並由瀏覽器控管啟動和終止作業,因此即使 PWA 尚未開啟或已關閉,這項服務仍可運作。服務工作人員會在自己的執行緒上執行,但服務工作人員的執行作業之間可能不會保留記憶體內狀態,因此請確保您想在每次執行作業中重複使用的任何項目,都位於 IndexedDB 或其他永久儲存空間。

如果服務工作人員尚未執行,只要在範圍內傳送網路要求,或收到觸發事件 (例如定期背景同步或推送訊息),服務工作人員就會啟動。

如果服務工作站閒置幾秒鐘,或忙碌太久,就會終止。這項作業的時機因瀏覽器而異。如果服務工作人員已終止,但發生會啟動服務工作人員的事件,服務工作人員就會重新啟動。

功能

已註冊且處於啟用狀態的 Service Worker 會使用執行生命週期與 PWA 主執行緒完全不同的執行緒。不過,根據預設,服務工作人員檔案本身沒有任何行為。不會快取或提供任何資源,這些都是程式碼需要執行的動作。您會在後續章節中瞭解如何操作。

服務工作站的功能不只代理或提供 HTTP 要求。此外,您還可使用其他功能,例如執行背景程式碼、傳送網頁推播通知及處理付款。我們會在「功能」中討論這些新增內容。

資源