咱們的應用程序的主進程主要負責渲染dom,執行交互請求,而Service Worker 是瀏覽器在後臺獨立於網頁運行的,它從新在後臺起了一個進程,它和應用的主進程互不影響,能夠同時執行。 sw能夠攔截和處理網絡請求,包括經過程序來管理緩存中的響應。在使用 service-worker 前,咱們必需要先在主進程中註冊它,而後才能在 service-worker 進程中編寫邏輯。css
//index.js. 註冊SW
if ("serviceWorker" in navigator) {
// Use the window load event to keep the page load performant
window.addEventListener("load", () => {
navigator.serviceWorker.register("/service-worker.js").then(registration=>{
console.log("register succces...")
}, err=>{
console.log("register error...",err)
});
});
}
複製代碼
咱們在根路徑下注冊了一個 SW,那SW 就能夠攔截對應服務下的全部請求。只須要監聽 fetch 事件,你就能夠任意的操縱請求,能夠返回從 CacheStorage 中讀的數據,也能夠經過 Fetch API 發起新的請求,甚至能夠 new 一個 Response,返回給頁面。html
//service-worker.js 簡單輸出一些文本
console.log('Hello from service-worker.js');
var cacheStorageKey = 'cachesName';
var cacheList = [
// 註冊成功後要當即緩存的資源列表
"/test.css",
"/index.js",
{
url: "/index.html",
revision: "383676" //-- revision 能夠經過工具插件workbox-webpack-plugin維護
}
]
// 當瀏覽器解析完 SW 文件時觸發 install 事件 安裝SW
self.addEventListener('install', function(e) {
// install 事件中通常會將 cacheList 中要換存的內容經過 addAll 方法,請求一遍放入 caches 中
e.waitUntil(
caches.open(cacheStorageKey).then(function(cache) {
return cache.addAll(cacheList)
})
);
});
// 激活時觸發 activate 事件
self.addEventListener('activate', function(e) {
// active 事件中一般作一些過時資源釋放的工做,匹配到就從 caches 中刪除
var cacheDeletePromises = caches.keys().then(cacheNames => {
return Promise.all(cacheNames.map(name => {
if (name !== cacheStorageKey) {
return caches.delete(name);
} else {
return Promise.resolve();
}
}));
});
e.waitUntil(
Promise.all([cacheDeletePromises])
);
});
// 緩存和返回請求
self.addEventListener('fetch', function(e) {
// 在此編寫緩存策略
e.respondWith(
// 能夠經過匹配緩存中的資源返回
caches.match(e.request)
// 也能夠從遠端拉取
fetch(e.request.url)
// 也能夠本身造
new Response('hell0')
// 也能夠經過吧 fetch 拿到的響應經過 caches.put 方法放進 caches
);
});
複製代碼
workbox 用於支持離線web apps的js庫, 是Google 根據SW的最佳實踐推出的官方框架,封裝了SW底層的API來監聽SW的安裝,激活,fetch事件以及緩存等相關邏輯處理,使用起來更簡單方便。webpack
Workbox 的主要功能是它的路由和緩存策略模塊。偵聽網頁的請求,並根據策略如何緩存和響應請求。這兩個功能的具體實現對應於它們的workerbox的workbox.routing ,workbox.strategies 和workbox.precaching。 經過 workbox.routing 模塊提供的路由控制和 workbox.strategies 模快提供的緩存策略控制幫助你作動態緩存。經過workbox.precaching 模塊來處理 Service Worker 靜態資源的預緩存。git
利用 workbox.precaching 模塊來處理 Service Worker 靜態資源的預緩存。github
// precache (預緩存) 靜態文件 一般項目中的 sw.js 源文件都是經過這樣預留一個空數組的方式來預緩存內容列表的
workbox.precaching.precacheAndRoute([
// 註冊成功後要當即緩存的資源列表
"/test.css",
"/index.js",
{
url: "/index.html",
revision: "383676" //-- revision 能夠經過工具插件workbox-webpack-plugin維護
}
]);
複製代碼
workbox.routing有3種方式來攔截匹配到的請求web
// string
workbox.routing.registerRoute(
'/logo.png',
handler
);
// RegExp
workbox.routing.registerRoute(
new RegExp('\\.js$'),
jsHandler
);
// Callback Function
const matchFunction = ({url, event}) => {
// Return true if the route should match
return false;
};
workbox.routing.registerRoute(
matchFunction,
handler
);
複製代碼
上述中的處理函數有兩種方式chrome
然而,利用 workbox.routing 模塊提供的路由控制和 workbox.strategies 模快提供的緩存策略控制幫助你作動態緩存。數組
這種策略當請求的路由有對應的 Cache 緩存結果就直接返回,在返回 Cache 緩存結果的同時會在後臺發起網絡請求拿到請求結果並更新 Cache 緩存,若是原本就沒有 Cache 緩存的話,直接就發起網絡請求並返回結果。瀏覽器
workbox.routing.registerRoute(
match, // 匹配的路由
workbox.strategies.staleWhileRevalidate()
);
複製代碼
這種策略就是當請求路由是被匹配的,就採用網絡優先的策略,也就是優先嚐試拿到網絡請求的返回結果,若是拿到網絡請求的結果,就將結果返回給客戶端而且寫入 Cache 緩存,若是網絡請求失敗,那最後被緩存的 Cache 緩存結果就會被返回到客戶端,這種策略通常適用於返回結果不太固定或對實時性有要求的請求,爲網絡請求失敗進行兜底。緩存
這個策略的意思就是當匹配到請求以後直接從 Cache 緩存中取得結果,若是 Cache 緩存中沒有結果,那就會發起網絡請求,拿到網絡請求結果並將結果更新至 Cache 緩存,並將結果返回給客戶端。這種策略比較適合結果不怎麼變更且對實時性要求不高的請求。
以前的疑問,若是網絡請求一直失敗的狀況, 是和 Stale While Revalidate的動做同樣的 ,是發請求,成功以後而後更新緩存,若是第一次也是失敗的,緩存中無對應結果,一樣也是是發請求,成功以後而後更新緩存。
比較直接的策略,直接強制使用正常的網絡請求,並將結果返回給客戶端,這種策略比較適合對實時性要求很是高的請求。能夠像以下方式使用 Network Only 策略:
這個策略也比較直接,直接使用 Cache 緩存的結果,並將結果返回給客戶端,這種策略比較適合一上線就不會變的靜態資源請求。能夠像以下方式使用 Cache Only 策略
查看啓動的SW
https sw 只工做在安全模式下
Web App Manifest Generator這個工具能夠幫助生成 manifest
策略