介紹
PWA(Progressive Web Apps) 一定是將來的移動開發(fā)趨勢。
Progressive Web Apps 比小程序還要方便,對于首次訪問的用戶可以直接在瀏覽器中進(jìn)行訪問,不需要安裝應(yīng)用。即使在比較糟糕的網(wǎng)絡(luò)環(huán)境下,也能夠快速地加載,且能夠推送相關(guān)消息, 也可以像原生應(yīng)用那樣添加至桌面或?yàn)g覽器主屏,能夠有全屏瀏覽的體驗(yàn)。
PWA 和 Service Worker 是什么關(guān)系?Service Worker 是一個運(yùn)行在瀏覽器后臺進(jìn)程里的js,基于它可以實(shí)現(xiàn)消息推送,靜默更新以及攔截和處理網(wǎng)絡(luò)請求,包括可編程的響應(yīng)緩存管理,是 PWA 的核心。
工作原理
Service worker 是一個完全獨(dú)立于 Web 頁面的 js 腳本,有他自己的生命周期。
每個 service worker 會對應(yīng)一個緩存池,每個緩存池有多個緩存?zhèn)}庫。
首先講講它的聲明周期,借用 Google 的一張圖片:
Serice Worker
若網(wǎng)站對應(yīng)的 cacheName 沒有 install,則首先觸發(fā) install事件。
若install失敗,則退出等待下次訪問再啟動;否則觸發(fā)activate事件。
在activate中,判斷當(dāng)前頁面是否在上文聲明的 filesToCache 列表中,如果是則接管網(wǎng)頁的顯示。
接管網(wǎng)頁以后,如果當(dāng)前內(nèi)存不足,會被殺死;否則等待處理fetch和message事件。這兩個事件一個是當(dāng)網(wǎng)絡(luò)請求時,或者其他網(wǎng)頁發(fā)出了消息時。 本文只講如何讓你的網(wǎng)頁無網(wǎng)絡(luò)也能訪問,沒有講這兩個事件,下一篇文章再給大家講講 service worker 深度使用。
從使用開始
準(zhǔn)備工作
首先你的站點(diǎn)必須支持https 。
其次,你至少得懂一點(diǎn) js開發(fā)。
最后,你得有一個 52 或以上的版本的 Chrome 用作調(diào)試。
注冊 Service Worker
首先,在你的網(wǎng)站根目錄下創(chuàng)建一個 service-worker.js 文件(文件名自定)。
這個 service-worker.js 文件必須放在跟目錄,因?yàn)?service workers 的作用范圍是根據(jù)其在目錄結(jié)構(gòu)中的位置決定的。
然后需要檢查瀏覽器是否支持 service workers,如果支持,就注冊 service worker,將下面代碼添加至網(wǎng)頁要加載的js中。
if('serviceWorker' in navigator) { //注冊上一步創(chuàng)建的js文件 navigator.serviceWorker .register('/service-worker.js') .then(function() { console.log('Service Worker Registered'); }); }
加載緩存
當(dāng)用戶訪問一個注冊了 service worker 的頁面時,會觸發(fā)一個叫install事件,所以我們首先對這個事件監(jiān)聽。
var cacheName = 'oslab-kymjs-blog';var filesToCache = [];self.addEventListener('install', function(e) { console.log('[ServiceWorker] Install'); e.waitUntil( caches.open(cacheName).then(function(cache) { console.log('[ServiceWorker] Caching app shell'); return cache.addAll(filesToCache); }) );});
當(dāng)監(jiān)聽到install事件以后,去緩存池打開名為 oslab-kymjs-blog 的緩存?zhèn)}庫。
每個 service worker 會對應(yīng)一個緩存池,每個緩存池有多個緩存?zhèn)}庫。
只要緩存被打開,就調(diào)用 cache.addAll() 并傳入一個 url 列表,然后加載這些資源并將響應(yīng)添加至緩存。
有個注意事項(xiàng)要知道 cache.addAll() 方法中,如果某個文件下載失敗了,那么整個緩存就會失敗,service worker 的install事件也將會失敗。而如果install失敗了,那么接下來 service worker 就完全不會工作了。 所以一定要注意,文件列表一定不要太長了,越長造成失敗的可能性就越高,每個要緩存的頁面越大失敗的可能性也越高。
調(diào)試
用 Chrome Developer Tools 調(diào)試 Service Worker 非常方便。
首先 run 起你本地的 server(我博客是 jekyll 生成的,所以直接用了 jekyll 服務(wù)),然后 Chrome 右上角三個點(diǎn),More Tools,Developer Tools。(mac快捷鍵 cmd+opt+i)
切換到 Application 視圖
你應(yīng)該能看到這樣的一個頁面
Serice Worker
首次運(yùn)行應(yīng)該顯示空的,看不到東西,刷新一下就可以了。但如果刷新后還是看不到,這意味著當(dāng)前打開的頁面沒有已經(jīng)被注冊的 Service Worker,檢查一下 注冊 步驟的js是否被加載了吧。
刷新前 注意勾選【update on reload】不然每次刷新都會起一個新的service worker,然后由于是串行執(zhí)行,會等待前一個執(zhí)行完,不然得手動點(diǎn)【skipWaiting】。
然后如果勾選了【update on reload】,可能會看到這個警告,無所謂,忽略它就好了。
Serice Worker
刪除無用緩存
當(dāng) service worker 開始啟動時,就會觸發(fā) activate 事件。 所以我們監(jiān)聽 activate 在這里更新緩存。
self.addEventListener('activate', function(e) { console.log('[ServiceWorker] Activate'); e.waitUntil( caches.keys().then(function(keyList) { return Promise.all(keyList.map(function(key) { console.log('[ServiceWorker] Removing old cache', key); if (key !== cacheName) { return caches.delete(key); } })); }) ); });
以上代碼表示,如果執(zhí)行到了 activate,首先判斷現(xiàn)在緩存池中的緩存?zhèn)}庫 cacheName 是否和我們聲明的 cacheName 同一個,如果不是,就清空緩存池中的無用緩存(install中下載新的緩存,activate 中刪除舊緩存)。所以建議大家在 cacheName 的末尾加一個版本號,這樣可以始終讓service worker 加載最新的緩存。
至此,就為我們的博客完整接入了 service worker。
咨詢熱線
010-85377344
135-21581588
微信客服
QQ客服
3026106565 點(diǎn)擊咨詢