Web Worker 和 Service Worker 如何提升網站效能,以及何時該使用 Web Worker 或 Service Worker。
本總覽說明 Web Worker 和 Service Worker 如何提升網站效能,以及何時應使用 Web Worker 或 Service Worker。請參閱本系列的其他文章,瞭解視窗和 Service Worker 通訊的特定模式。
Worker 如何改善網站
瀏覽器會使用單一執行緒 (主執行緒) 執行網頁中的所有 JavaScript,以及執行轉譯網頁和執行垃圾收集等工作。執行過多 JavaScript 程式碼可能會阻斷主執行緒,導致瀏覽器延遲執行這些工作,進而造成使用者體驗不佳。
在 iOS/Android 應用程式開發中,為了確保應用程式的主執行緒能自由回應使用者事件,常見的做法是將作業卸載至其他執行緒。事實上,在最新版本 Android 中,如果主執行緒遭到封鎖的時間過長,應用程式就會當機。
在網路上,JavaScript 是以單一執行緒的概念設計,缺乏實作多執行緒模型所需的功能,例如共用記憶體。
儘管有這些限制,您仍可使用 worker 在背景執行緒中執行指令碼,在不干擾主執行緒的情況下執行工作,在網路上實現類似的模式。Worker 是在獨立執行緒上執行的完整 JavaScript 範圍,不含任何共用記憶體。
本文將介紹兩種不同的 worker (Web worker 和 Service Worker)、兩者的異同,以及在正式版網站中使用這些 worker 的最常見模式。
Web Worker 和 Service Worker
相似處
網站可使用兩種 worker:Web worker 和 service worker。這些機型有幾個共通點:
- 兩者都在次要執行緒中執行,因此 JavaScript 程式碼可以執行,而不會阻擋主執行緒和使用者介面。
- 他們無法存取
Window和Document物件,因此無法直接與 DOM 互動,且對瀏覽器 API 的存取權有限。
相異處
您可能會認為,大多數可委派給 Web Worker 的工作都可以在 Service Worker 中完成,反之亦然,但兩者之間有重要差異:
- 與網頁 worker 不同,Service Worker 可讓您攔截網路要求 (透過
fetch事件),並在背景監聽 Push API 事件 (透過push事件)。 - 一個網頁可以產生多個 Web Worker,但單一 Service Worker 會控制註冊範圍內的所有活動分頁。
- Web worker 的生命週期與所屬分頁緊密結合,而 service worker 的生命週期則與分頁無關。因此,關閉執行 Web Worker 的分頁會終止該 Worker,而 Service Worker 則可在背景繼續執行,即使網站沒有開啟任何有效分頁也一樣。
用途
這兩種 worker 的差異,可做為選擇使用哪一種的依據:
Web worker 的用途通常與將工作 (例如繁重的運算) 卸載至次要執行緒有關,以避免封鎖 UI。
- 範例:PROXX 電玩遊戲的開發團隊希望盡可能釋出主執行緒,以便處理使用者輸入內容和動畫。為此,他們使用 Web Worker,在獨立執行緒上執行遊戲邏輯和狀態維護。
Service Worker 工作通常與網路 Proxy、處理背景工作,以及快取和離線等作業較相關。
範例:在 Podcast PWA 中,您可能想允許使用者下載完整單集,以便離線收聽。Service Worker (尤其是 Background Fetch API) 可用於達成這個目的。這樣一來,如果使用者在下載集數時關閉分頁,工作就不會中斷。
工具與程式庫
視窗和 worker 通訊可透過不同的低階 API 實作。幸好,有些程式庫會將這項程序抽象化,處理最常見的用途。在本節中,我們將介紹其中兩個分別負責視窗與 Web Worker 和 Service Worker 之間通訊的程式庫:Comlink 和 Workbox。
Comlink
Comlink 是小型 (1.6k) RPC 程式庫,可處理建構使用 Web Worker 的網站時,許多基礎細節。PROXX 和 Squoosh 等網站都曾使用過。如需動機摘要和程式碼範例,請參閱這裡。
Workbox
Workbox 是熱門的程式庫,可用於建構使用 Service Worker 的網站。其中包含一組最佳做法,例如快取、離線、背景同步等。workbox-window 模組提供一種便利的方式,可在 Service Worker 和網頁之間交換訊息。
後續步驟
本系列其餘部分著重於視窗和 Service Worker 通訊模式:
- 指令式快取指南:從網頁呼叫 Service Worker,預先快取資源 (例如預先擷取情境)。
- 廣播更新:從 Service Worker 呼叫網頁,通知重要更新 (例如網站有新版本)。
- 雙向通訊:將工作委派給 Service Worker (例如大量下載),並隨時通知頁面進度。
如要瞭解視窗和網路 worker 的通訊模式,請參閱「使用網路 worker 在瀏覽器的主執行緒外執行 JavaScript」。