【Web微知識系列】 Service Workers

更新於 發佈於 閱讀時間約 15 分鐘

Service Workers

Service worker與Web workers相同,也都是一段運行在瀏覽器後台的腳本,提供一些不需要與頁面直接交互的功能(操作dom),主要處理網路相關的問題,可以攔截網路請求進行相對應的優化動作,我們把它想像成與伺服器之間的代理服務器可能會比較容易理解,當網路環境不佳時便回應快取資源,待網路順暢後同步最新資料,因此能提高更好的離線體驗,我們可能會想說為什麼有了Web workers、AppCache這類的API還需要Service worker呢?因為這些既有的功能主要都由我們自己去handle一些細緻的操作,過程非常繁瑣,因此發展出Service worker,背後幫我們解決掉許多事情(error handler、http request listener…)

功能

  • 資源快取
  • 離線應用
  • 多頁面傳遞(Post Message)
  • 推播通知
  • 後台自動更新

生命週期

  • 註冊Service worker
  • 註冊之後瀏覽器會在背景啟動Service Worker的安裝
  • 安裝過程中會將設定的靜態資源進行緩存,待所有靜態資源緩存成功後進入Activated狀態
  • 如果過程中任何一個資源不能成功緩存則代表安裝失敗,進入error,待重新安裝
  • 進入Activated狀態後進行監聽,當request或post message發生時則觸發相對應動作
  • Terminated狀態由瀏覽器決定是否銷毀,如果長期不使用或者記憶體不足時,則可能銷毀這個worker

Worker中常使用的事件

簡單實作Service Worker

註冊Service Worker

<html>
<body>
<script>
if ('serviceWorker' in navigator) {
navigator.serviceWorker.register('./sw.js')
.then(reg => console.log(reg))
.catch(err => console.log(err));
}
</script>
</body></html>

撰寫sw.js腳本檔

const cacheUrl = [
'./index.html',
'./script.js',
'./car.svg'
];
const cacheName = 'precache' + (self.registration ? self.registration.scope: '');
self.addEventListener('install', (event) => {
event.waitUntil(
caches.open(cacheName)
.then((cache) => {
console.log('open cache');
return cache.addAll(cacheUrl);
});
);
});
//clean cached files
self.addEventListener('activate', (event) => {
event.waitUntil(
caches.keys().then(function(cacheNames) {
var promiseArr = cacheNames.map(function(item) {
if (item !== cacheName) {
return caches.delete(item);
}
})
return Promise.all(promiseArr);
})
)
});
self.addEventListener('fetch', (event) => {
//cache first
event.respondWith(caches.match(event.request).then(res => {
if (res) {
console.log('match');
return res;
}
return fetch(event.request);
}));
});

cache的策略

Cache only

這種方式下任何請求都會從Cache storage取得
self.addEventListener('fetch', function(event) {
event.respondWith(caches.match(event.request));
});

Network only

這種方式下任何請求都不會跟Cache storage打交道,直接向後端發送
self.addEventListener('fetch', function(event) {
event.respondWith(fetch(event.request));
// or simply don't call event.respondWith, which
// will result in default browser behaviour
});

Cache first

頁面發送request時會先從Cache storage中存取若發現該請求尚未被緩存到則會改為Network請求
self.addEventListener('fetch', function(event) {
event.respondWith(
caches.match(event.request).then(function(response) {
return response || fetch(event.request);
})
);
});

Network first

頁面發送request時會先由Network向後端請求,若請求失敗則改由Cache storage請求
self.addEventListener('fetch', function(event) {
event.respondWith(
fetch(event.request).catch(function() {
return caches.match(event.request);
})
);
});

Cache & network race

頁面發送request時同時向Cache及Network請求,哪一個請求先回來則使用該response
// Promise.race is no good to us because it rejects if// a promise rejects before fulfilling. Let's make a proper// race function:function promiseAny(promises) {
return new Promise((resolve, reject) => {
// make sure promises are all promises
promises = promises.map(p => Promise.resolve(p));
// resolve this promise as soon as one resolves
promises.forEach(p => p.then(resolve));
// reject if all promises reject
promises.reduce((a, b) => a.catch(() => b))
.catch(() => reject(Error("All failed")));
});
}; self.addEventListener('fetch', function(event) {
event.respondWith(
promiseAny([
caches.match(event.request),
fetch(event.request)
])
);
});

Cache then network

頁面發送request時先由Cache storage取得顯示給user,然後再由Network取得後更新資料。
Code in Page
var networkDataReceived = false;    startSpinner();    // fetch fresh data
var networkUpdate = fetch('/data.json').then(function(response) {
return response.json();
}).then(function(data) {
networkDataReceived = true;
updatePage();
}); // fetch cached data
caches.match('/data.json').then(function(response) {
if (!response) throw Error("No data");
return response.json();
}).then(function(data) {
// don't overwrite newer network data
if (!networkDataReceived) {
updatePage(data);
}
}).catch(function() {
// we didn't get cached data, the network is our last hope:
return networkUpdate;
}).catch(showErrorMessage).then(stopSpinner);
Code in the ServiceWorker: 當網路請求資源成功時,更新緩存內容
self.addEventListener('fetch', function(event) {
event.respondWith(
caches.open('mysite-dynamic').then(function(cache) {
return fetch(event.request).then(function(response) {
cache.put(event.request, response.clone());
return response;
});
})
);
});

相關概念

  • Service worker與Web worker一樣不能直接對dom結構進行操作,僅透過postMessage相互溝通
  • 基於安全考量Service worker只能運行在https的環境之上,畢竟修改網路請求的能力是相對危險的
  • 使用Service worker來進行cache優於一般worker的原因是Service worker能夠細緻的控制,例如發生error時直接於worker內部進行相對應處理,而一般worker僅能於產生worker的那個頁面進行,且API相對較少

實際操作

Service worker相關的library

sw-precache主要根據配置來產生service worker腳本檔的工具,而sw-toolbox則是sw-precache的加強工具,可以針對動態請求進行細部控制

各家瀏覽器支援狀況

為什麼會看到廣告
avatar-img
118會員
267內容數
哈囉,我是阿Han,是一位 👩‍💻 軟體研發工程師,喜歡閱讀、學習、撰寫文章及教學,擅長以圖代文,化繁為簡,除了幫助自己釐清思路之外,也希望藉由圖解的方式幫助大家共同學習,甚至手把手帶您設計出高品質的軟體產品。
留言0
查看全部
avatar-img
發表第一個留言支持創作者!
阿Han的沙龍 的其他內容
Cookie簡介與個人隱私議題 在談Cookieless之前我們先來了解什麼是Cookie,這裡的Cookie並不是餅乾的意思,而是為了讓人們在網路上通訊時,能夠創造更無縫的體驗,想像一下,假設我們在使用網站時,每切換一頁就要進行登入一次,我想大部分的人都已經抓狂並放棄使用的吧! 而Cookie的出
我們前一篇有介紹過「Cookieless時代趨勢來臨,與我們息息相關的隱私與行銷方式如何應對呢?」建議先行閱讀,裡面包含Cookie的基本觀念,以及為什麼要捨棄的原因,接下來才進入到本篇的主軸,將會針對FLoC的基本原理、是否能解決個人隱私議題為主軸進行探討。 FLoC的全名是 Federated
延續前一篇談論的主題「Cookieless系列: Floc能解決隱私議題嗎?」,我們已經瞭解到FLoC這項技術解決的隱私的什麼問題,也明白事實上還是存在著風險的,因此Google準備捨棄FLoC迎接新的技術Google Topic,我們也會針對這項技術進行簡單的介紹,共同來學習頂尖的科技公司如何針對
今天來聊聊我們常常使用的網頁,背後怎麼讓我們用的更順暢的一門傳輸方式,HTTP Keep-Alive,透過一點點的小改變,讓傳輸效率提升,減少非必要的浪費。 當我們溝通的過程中沒有KeepAlive的狀況下,會有多次往來的狀況,這樣對雙方來說開銷成本是非常大的,因此為了改善這個現象,加入了一個機制,
我們前一篇介紹了「【Web系列】訂閱技術的基石,RSS Feed是什麼?」,相信也對於訂閱的機制具備一定的認識了,雖然RSS已經能夠滿足我們訂閱的一些基本需求,但由於主要的訂閱端還是定期去檢查更新資訊,因此假設我們想要在最短時間內掌握最新資訊時,仍會有一些延遲,再者也非常浪費頻寬。 我們為什麼不能改
超文本傳輸協定(HyperText Transfer Protocol,縮寫: HTTP),主要做為數據通訊的基礎協定,舉凡我們上網的網頁、圖片…,都是由HTTP協定為基底標準,讓服務端與用戶端可以相互通訊,達到互動、傳遞資訊的作用,而從最初版的單向傳輸也隨著時代的演進,應用漸趨複雜的趨勢下慢慢優化
Cookie簡介與個人隱私議題 在談Cookieless之前我們先來了解什麼是Cookie,這裡的Cookie並不是餅乾的意思,而是為了讓人們在網路上通訊時,能夠創造更無縫的體驗,想像一下,假設我們在使用網站時,每切換一頁就要進行登入一次,我想大部分的人都已經抓狂並放棄使用的吧! 而Cookie的出
我們前一篇有介紹過「Cookieless時代趨勢來臨,與我們息息相關的隱私與行銷方式如何應對呢?」建議先行閱讀,裡面包含Cookie的基本觀念,以及為什麼要捨棄的原因,接下來才進入到本篇的主軸,將會針對FLoC的基本原理、是否能解決個人隱私議題為主軸進行探討。 FLoC的全名是 Federated
延續前一篇談論的主題「Cookieless系列: Floc能解決隱私議題嗎?」,我們已經瞭解到FLoC這項技術解決的隱私的什麼問題,也明白事實上還是存在著風險的,因此Google準備捨棄FLoC迎接新的技術Google Topic,我們也會針對這項技術進行簡單的介紹,共同來學習頂尖的科技公司如何針對
今天來聊聊我們常常使用的網頁,背後怎麼讓我們用的更順暢的一門傳輸方式,HTTP Keep-Alive,透過一點點的小改變,讓傳輸效率提升,減少非必要的浪費。 當我們溝通的過程中沒有KeepAlive的狀況下,會有多次往來的狀況,這樣對雙方來說開銷成本是非常大的,因此為了改善這個現象,加入了一個機制,
我們前一篇介紹了「【Web系列】訂閱技術的基石,RSS Feed是什麼?」,相信也對於訂閱的機制具備一定的認識了,雖然RSS已經能夠滿足我們訂閱的一些基本需求,但由於主要的訂閱端還是定期去檢查更新資訊,因此假設我們想要在最短時間內掌握最新資訊時,仍會有一些延遲,再者也非常浪費頻寬。 我們為什麼不能改
超文本傳輸協定(HyperText Transfer Protocol,縮寫: HTTP),主要做為數據通訊的基礎協定,舉凡我們上網的網頁、圖片…,都是由HTTP協定為基底標準,讓服務端與用戶端可以相互通訊,達到互動、傳遞資訊的作用,而從最初版的單向傳輸也隨著時代的演進,應用漸趨複雜的趨勢下慢慢優化
你可能也想看
Google News 追蹤
Thumbnail
現代社會跟以前不同了,人人都有一支手機,只要打開就可以獲得各種資訊。過去想要辦卡或是開戶就要跑一趟銀行,然而如今科技快速發展之下,金融App無聲無息地進到你生活中。但同樣的,每一家銀行都有自己的App時,我們又該如何選擇呢?(本文係由國泰世華銀行邀約) 今天我會用不同角度帶大家看這款國泰世華CUB
Thumbnail
嘿,大家新年快樂~ 新年大家都在做什麼呢? 跨年夜的我趕工製作某個外包設計案,在工作告一段落時趕上倒數。 然後和兩個小孩過了一個忙亂的元旦。在深夜時刻,看到朋友傳來的解籤網站,興致勃勃熬夜體驗了一下,覺得非常好玩,或許有人玩過了,但還是想寫上來分享紀錄一下~
Thumbnail
某單位志工服務時數記錄在檔案內,需匯入衛福部志工系統,但由於志工多、檔案多,進行人工計算耗時費工且常累計算錯。故提此法改善,提高效率。文章內容包含了作業流程、作業說明、實例說明、改善前後、展開運用和設計編寫。
Thumbnail
※ 靜態資源回傳 ※ 什麼是靜態資源: 定義:是指事先準備好的資源,這些資源在伺服器上是靜態的、不會隨著每個請求而改變。 資源通常包括: 靜態 HTML 文件。 CSS。 圖像(Image)。 Video。 字體文件:google fonts。 favicon:網頁名稱旁邊的ico
Thumbnail
  在開始操作Web Service之前,要先做一些前置作業IIS的安裝,再開始建置Web Service相關內容,最後就是連線測試。   IIS(Internet Information Services)是網際網路資訊服務,可以讓網站使用HTTP/HTTPS、FTP/FTPS、SMTP 等等的
Thumbnail
一、什麼是Web Service?   簡單說就是「服務」的概念,人與人間、電腦與電腦間都是一樣的,一個是人與人的一來一回交流,媒介是語言中文,另一個則是個人電腦與伺服器的交流,媒介是HTTP/Internet,那麼有了媒介,就會有共同格式才能做
Thumbnail
不知道需求的服務是一種自嗨。我們的分成兩個服務類別,一個是簡單家訪,另一個是打掃環境。服務有點像一份田野調查,需要細細的感受當地的環境和人文,需要更長期的了解和觀察,需要真正認識、愛上一個地方,才可以真正服務到社區。 我選擇的是打掃組。因著我的專業和其他任務分組,我希望更了解這
Thumbnail
這篇文章分享了在遠端工作方面的 5 個經驗和心得,包括如何有效管理工作任務、活動與會議管理、工作訊息處理、如何劃分工作與生活界線以及遠端工作設備推薦。 如果你是遠端工作者,這篇文章可以提供你一些實用的建議。
Thumbnail
Service Worker 是用於客戶端的攔截器,可以使用 Cache Storage 和 IndexDB,並有自己的生命週期。Web Worker 用於處理可能會使用到大量運算且不希望影響到使用者體驗的任務。Shared Worker 可以在相同 Domain 的不同頁面上共享訊息。
本文探討服務業的真諦以及作者對於提供服務的信念和體悟。透過兩次購物經驗,分享不同店主的服務態度,並對服務的觀念給予詮釋。這是一篇關於提供服務給予他人理念的分享和反思。
Thumbnail
在職重服務中,不見得每個人一開始就準備好就業的狀態,而是如何一步一步走向準備好就業的狀態。
Thumbnail
現代社會跟以前不同了,人人都有一支手機,只要打開就可以獲得各種資訊。過去想要辦卡或是開戶就要跑一趟銀行,然而如今科技快速發展之下,金融App無聲無息地進到你生活中。但同樣的,每一家銀行都有自己的App時,我們又該如何選擇呢?(本文係由國泰世華銀行邀約) 今天我會用不同角度帶大家看這款國泰世華CUB
Thumbnail
嘿,大家新年快樂~ 新年大家都在做什麼呢? 跨年夜的我趕工製作某個外包設計案,在工作告一段落時趕上倒數。 然後和兩個小孩過了一個忙亂的元旦。在深夜時刻,看到朋友傳來的解籤網站,興致勃勃熬夜體驗了一下,覺得非常好玩,或許有人玩過了,但還是想寫上來分享紀錄一下~
Thumbnail
某單位志工服務時數記錄在檔案內,需匯入衛福部志工系統,但由於志工多、檔案多,進行人工計算耗時費工且常累計算錯。故提此法改善,提高效率。文章內容包含了作業流程、作業說明、實例說明、改善前後、展開運用和設計編寫。
Thumbnail
※ 靜態資源回傳 ※ 什麼是靜態資源: 定義:是指事先準備好的資源,這些資源在伺服器上是靜態的、不會隨著每個請求而改變。 資源通常包括: 靜態 HTML 文件。 CSS。 圖像(Image)。 Video。 字體文件:google fonts。 favicon:網頁名稱旁邊的ico
Thumbnail
  在開始操作Web Service之前,要先做一些前置作業IIS的安裝,再開始建置Web Service相關內容,最後就是連線測試。   IIS(Internet Information Services)是網際網路資訊服務,可以讓網站使用HTTP/HTTPS、FTP/FTPS、SMTP 等等的
Thumbnail
一、什麼是Web Service?   簡單說就是「服務」的概念,人與人間、電腦與電腦間都是一樣的,一個是人與人的一來一回交流,媒介是語言中文,另一個則是個人電腦與伺服器的交流,媒介是HTTP/Internet,那麼有了媒介,就會有共同格式才能做
Thumbnail
不知道需求的服務是一種自嗨。我們的分成兩個服務類別,一個是簡單家訪,另一個是打掃環境。服務有點像一份田野調查,需要細細的感受當地的環境和人文,需要更長期的了解和觀察,需要真正認識、愛上一個地方,才可以真正服務到社區。 我選擇的是打掃組。因著我的專業和其他任務分組,我希望更了解這
Thumbnail
這篇文章分享了在遠端工作方面的 5 個經驗和心得,包括如何有效管理工作任務、活動與會議管理、工作訊息處理、如何劃分工作與生活界線以及遠端工作設備推薦。 如果你是遠端工作者,這篇文章可以提供你一些實用的建議。
Thumbnail
Service Worker 是用於客戶端的攔截器,可以使用 Cache Storage 和 IndexDB,並有自己的生命週期。Web Worker 用於處理可能會使用到大量運算且不希望影響到使用者體驗的任務。Shared Worker 可以在相同 Domain 的不同頁面上共享訊息。
本文探討服務業的真諦以及作者對於提供服務的信念和體悟。透過兩次購物經驗,分享不同店主的服務態度,並對服務的觀念給予詮釋。這是一篇關於提供服務給予他人理念的分享和反思。
Thumbnail
在職重服務中,不見得每個人一開始就準備好就業的狀態,而是如何一步一步走向準備好就業的狀態。