做者: Felix Gerschau
譯者:前端小智
來源:Felix Gerschau
最近開源了一個 Vue 組件,還不夠完善,歡迎你們來一塊兒完善它,也但願你們能給個 star 支持一下,謝謝各位了。javascript
github 地址:https://github.com/qq44924588...css
Service Worker 是 Chrome 團隊提出和力推的一個 WEB API,用於給 web 應用提供高級的可持續的後臺處理能力。該 WEB API 標準起草於 2013 年,於 2014 年歸入 W3C WEB 標準草案,當前還在草案階段。html
Service Worker 最主要的特色是:在頁面中註冊並安裝成功後,運行於瀏覽器後臺,不受頁面刷新的影響,能夠監聽和截攔做用域範圍內全部頁面的 HTTP 請求。前端
相似一個服務器與瀏覽器之間的中間人角色,若是網站中註冊了service worker
那麼它能夠攔截當前網站全部的請求,進行判斷(須要編寫相應的判斷程序),若是須要向服務器發起請求的就轉給服務器,若是能夠直接使用緩存的就直接返回緩存再也不轉給服務器。從而大大提升瀏覽體驗。vue
Service Worker
能夠啓用之前原生應用程序專有的一組功能。 Service Worker 的初稿已於2014年發佈,如今全部主流瀏覽器都支持它們。java
就像已經指出的定義同樣,Service Worker 是網絡代理。 這意味着它們能夠控制頁面中的全部網絡請求,而且能夠對其進行編程,使用緩存的進行響應。git
HTTPS
。除了使用本地開發環境調試時(如域名使用 localhost
)註冊 Service Worker 不須要太多代碼,只須要一個用於Service Worker
代碼的 JS 文件,通常取名爲 service-worker.js
github
// 首先檢查瀏覽器是否支持 Service Worker if ('serviceWorker' in navigator) { navigator.serviceWorker .register('/sw/service-worker.js') .then(function(registration) { console.log(registration); }) .catch(function(err) { console.log(err); }); }
其實關鍵代碼只有一行:web
navigator.serviceWorker.register('/sw/service-worker.js')
注意:面試
Service Worker 的註冊路徑決定了其 scope
默認做用範圍。示例中 service-worker.js
是在 /sw
路徑下,這使得該 Service Worker 默認只會收到 /sw
路徑下的 fetch
事件。若是存放在網站的根路徑下,則將會收到該網站的全部 fetcg
事件。
若是但願改變它的做用域,可在第二個參數設置 scope
範圍。示例中將其改成了根目錄,即對整個站點生效。
另外應意識到這一點:Service Worker 沒有頁面做用域的概念,做用域範圍內的全部頁面請求都會被當前激活的 Service Worker 所監控。
在本節中,我將進一步詳細介紹Service Worker的功能,包括一些小代碼示例。
服務工做者啓用如下功能,這些功能也是 PWA
的核心:
Service Worke 經過緩存資源和攔截網絡請求來提供離線功能,這些請求能夠與先前緩存的資源一塊兒使用,而不是從新請求服務器。
咱們能夠從中得出兩個步驟:
這兩個步驟都利用了Cache API,它由 Web Workers 和瀏覽器使用,而且爲咱們提供了用於網絡請求的存儲機制。
對 Web 和服務工做人員上下文的 localStorage
訪問被阻止,以防止併發性問題。做爲一種替代方案,IndexedDB
能夠用於存儲大量數據。
預緩存
預緩存是一個術語,描述了在 Service Worker 處於激活狀態以前下載和緩存文件。 它是在 Service Worker 生命週期的「install
」步驟中完成的。 一旦 Service Worker 處於激活狀態,它將準備爲緩存中的文件提供服務。
一般,咱們要緩存 Application Shell
,這是運行網站所需的最少代碼量。 若是開發了本機應用程序,那麼這就是您將上傳到應用程序商店的代碼包。 這包括全部必需的基本JavaScript,HTML和圖片。
self.addEventListener('install', function(event) { event.waitUntil( caches.open(currentCache.offline).then(function(cache) { return cache.addAll([ '/static/images/offline.svg', '/static/html/offline.html', ]); }); ); });
從緩存中處理請求
在此階段,咱們已經將全部應用程序代碼存儲在緩存中,而且Service Worker
已處於激活
即運行於瀏覽器後臺。
如今惟一缺乏的是監聽 fetch
事件並從緩存中返回結果。能夠經過 fetch
事件能夠攔截到當前做用域範圍內的 http/https 請求,而且給出本身的響應。結合 Fetch API ,能夠簡單方便地處理請求響應,實現對網絡請求的控制。
self.addEventListener('fetch', function(event) { event.respondWith( caches.match(event.request).then(function(response) { return response || fetch(event.request); }) ); });
在本例中,咱們儘量使用緩存的內容進行響應。做爲回退,咱們發出一個網絡請求。
這裏實現了一個緩存優先
、降級處理
的策略邏輯:監控全部 http
請求,當請求資源已經在緩存裏了,直接返回緩存裏的內容;不然使用 fetch
API 繼續請求,若是是 圖片或 css
、js
資源,請求成功後將他們加入緩存中;若是是離線狀態或請求出錯,則降級返回預緩存的離線內容。
正如在引言中已經提到的那樣,Service Worker 與其餘服務工做者在一個單獨的線程上運行,因此即便關閉頁面,它們也能夠執行其代碼。 此功能對於執行後臺同步和提供推送通知很重要。
後臺同步
用戶離開頁面後,後臺同步一般用於同步數據。
例如,在手機上編輯文檔後,咱們寫完會點擊「保存」並離開頁面。 若是在編輯文檔期間鏈接斷開,咱們必須等待鏈接恢復才能保存文檔。
後臺同步的目的是解決這個問題,一旦鏈接從新創建,自動發送數據。
來看一個示例:
app.js
navigator.serviceWorker.ready.then((registration) => { return registration.sync.register('sync-save-document'); });
service-worker.js
self.addEventListener('sync', (event) => { if (event.tag === 'sync-save-document') { event.waitUntil(saveDocument()); } });
saveDocument
是一個返回 Promise
,若是被拒絕(例如因爲網絡問題),同步將自動重試。
要注意的一件事是,同步標記必須是惟一的。 例如,若是我要安排5個「message
」類型的後臺同步,則只有最後一個會經過。 所以,在這種狀況下,每一個標籤都應具備惟一的標識符。
按期後臺同步
按期後臺同步解決與正常後臺同步不一樣的問題。 該API可用於在後臺更新數據,而沒必要等待用戶。
這對不少應用程序都頗有用。有了這項技術,用戶能夠在沒有互聯網鏈接的狀況下閱讀最新的新聞文章。
爲了防止濫用這一功能,同步的頻率取決於瀏覽器爲每一個網站設置的站點參與度分數。若是你常常打開一個網頁應用,這個頻率最多能夠達到12個小時。
要實現此目的一個要求是,該網站已做爲移動設備上的 PWA
安裝並添加到主屏幕。
Service Worker另外一個相似本機的特性是推送通知。咱們一般經過手機短信或社交媒體通知的形式知道它們,但它們也能夠在臺式電腦上使用。
除Safari以外,全部主流瀏覽器都支持它們,而Safari對桌面應用程序有本身的實現。
要使用推送通知,須要設置一臺服務器,該服務器會將通知推送給全部客戶端。 因爲Service Worker在後臺在另外一個線程上運行,所以即便頁面當前未打開,用戶也能夠看到推送通知。
推送的實現有兩步:
不一樣瀏覽器須要用不一樣的推送消息服務器。以 Chrome 上使用 Google Cloud Messaging<GCM>
做爲推送服務爲例,第一步是註冊 applicationServerKey
(經過 GCM 註冊獲取),並在頁面上進行訂閱或發起訂閱。每個會話會有一個獨立的端點(endpoint
),訂閱對象的屬性(PushSubscription.endpoint
) 即爲端點值。將端點發送給服務器後,服務器用這一值來發送消息給會話的激活的 Service Worker (經過 GCM 與瀏覽器客戶端溝通)。
除了 Safari 和 IE/Edge,大部分現代瀏覽器都已經獲得了支持。
但願經過本文介紹基本概念和特性,可讓你更好地理解Service Worker。
代碼部署後可能存在的BUG無法實時知道,過後爲了解決這些BUG,花了大量的時間進行log 調試,這邊順便給你們推薦一個好用的BUG監控工具 Fundebug。
原文:https://felixgerschau.com/ser...
文章每週持續更新,能夠微信搜索「 大遷世界 」第一時間閱讀和催更(比博客早一到兩篇喲),本文 GitHub https://github.com/qq449245884/xiaozhi 已經收錄,整理了不少個人文檔,歡迎Star和完善,你們面試能夠參照考點複習,另外關注公衆號,後臺回覆福利,便可看到福利,你懂的。