咱们的应用程序的主进程主要负责渲染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
策略