介紹
Service Workder相當于浏覽器與web應用程式之間的代理伺服器,可以捕獲請求事件并做相應處理;目前主要用于離線應用以及消息推送及背景同步等;
特性
- 無法直接通路和操作DOM
- 在長時間不用時會被中止并在下次需要時重新開機;
- 可以通路和操作
indexedDB API
- 推薦使用HTTPS
- 内部實作基于
Promise
生命周期
-
事件是SW的第一個事件,隻會發生一次,使用install
監測是否安裝成功;e.waitUtil()
- 生命周期中的主要圍繞兩個事件
和install
:activate
前後的生命周期包括install
和installing
,installed
前後的生命周期包括activate
和activating
;最後SW不用或者新舊更替時經曆的生命周期時activated
;redundant
- 在安裝成功并處于
之前,不會處理活動狀态
;functional events
- 處于
狀态才可以處理activated
;functional events: fetch/push/sync

支援的事件
使用
demo位址
-
注冊
可以通過
方法注冊一個serviceWorker.register()
執行個體,它是由Service Worker
實作的,Promise
後在resolve
函數中拿到then
對象;包含了所注冊sw的相關資訊,如下圖:registration
具體注冊實作的過程如下圖:Service Worker簡介 if ('serviceWorker' in navigator) { window.addEventListener('load', () => { navigator.serviceWorker.register('sw.js') .then(registration => { console.log('sw installed: ', registration); }) .catch(err => console.log('sw installed failed: ', err)) }) }
-
安裝 Service Worker
在本文生命周期一節中,根據圖示我們看到
事件中可以通過install
方法建立一個Promise對象來等待安裝完成,安裝完成後則event.waitUntil()
被Promise
resolve
,然後我們可以打開緩存并存緩存需要緩存的資源;
具體實作如下:
var CACHE_NAME = 'sw-cache'; var CACHE_URLS = ['./index.html', './index.js', './public/equal.png', './public/icon.png']; self.addEventListener('install', e => { e.waitUntil( caches.open(CACHE_NAME) // 打開緩存 .then(cache => cache.addAll(CACHE_URLS)) ) }
-
捕獲請求并處理
具體實作如下:
self.addEventListener('fetch', e => { e.respondWith( caches.match(e.request) // 檢測緩存資源和請求資源是否比對, e.request具有以下屬性:url/method/header/body .then(res => { if (res) { return res; } console.log('loaded from sw'); }) ) })
- 更新
- 自動更新
的更新遵循以下步驟(來自谷歌開發者):Service Workder
- 更新您的服務工作線程 JavaScript 檔案。 使用者導航至您的站點時,浏覽器會嘗試在背景重新下載下傳定義 Service Worker 的腳本檔案。 如果 Service Worker 檔案與其目前所用檔案存在位元組差異,則将其視為新 Service Worker。
- 新 Service Worker 将會啟動,且将會觸發 install 事件。
- 此時,舊 Service Worker 仍控制着目前頁面,是以新 Service Worker 将進入 waiting 狀态。
- 當網站上目前打開的頁面關閉時,舊 Service Worker 将會被終止,新 Service Worker 将會取得控制權。
- 新 Service Worker 取得控制權後,将會觸發其 activate 事件。
的狀态,而舊的sw仍然運作并且處于waiting to active
狀态;active
關閉上圖中的标簽頁Service Worker簡介
并重新打開頁面後:如下圖,我們可以看到新的id為128的sw已經運作并處于http://127.0.0.1:5500/service%20worker/index.html
狀态;active
當然,可以通過調用Service Worker簡介
跳過等待階段,在安裝完成後立即激活;self.skipWaiting()
- 手動更新
navigator.serviceWorker.register('/sw.js').then(reg => { // something later reg.update(); })
- 自動更新
-
删除舊緩存
由于浏覽器對
可用的磁盤空間有嚴格限制,是以更新Service Worker
Service Worker
時,我們需要進行緩存管理;
根據
的生命周期,我們可以看到在Service Worker
階段active
處于活躍狀态,即可以管理舊sw相關的資源;Service Worker
self.addEventListener('activate', function(event) { // 建立需要儲存的緩存白名單 var cacheWhitelist = ['pages-cache-v1', 'blog-posts-cache-v1']; event.waitUntil( caches.keys().then(function(cacheNames) { return Promise.all( cacheNames.map(function(cacheName) { if (cacheWhitelist.indexOf(cacheName) === -1) { return caches.delete(cacheName); } }) ); }) ); });
效果示範
Service Worker簡介
參考文獻:
- https://developers.google.com/web/fundamentals/primers/service-workers/?hl=zh-CN
- https://developer.mozilla.org/zh-CN/docs/Web/API/Service_Worker_API/Using_Service_Workers
- https://developers.google.com/web/fundamentals/primers/service-workers/lifecycle?hl=zh-CN