Workbox
Workbox
引入
// 首先引入 Workbox 框架
importScripts("https://g.alicdn.com/kg/workbox/3.3.0/workbox-sw.js");
workbox.setConfig({
modulePathPrefix: "https://g.alicdn.com/kg/workbox/3.3.0/",
});
workbox.precaching([
// 注册成功后要立即缓存的资源列表
]);
// html的缓存策略
workbox.routing.registerRoute(
new RegExp(".*.html"),
workbox.strategies.networkFirst()
);
workbox.routing.registerRoute(
new RegExp(".*.(?:js|css)"),
workbox.strategies.cacheFirst()
);
workbox.routing.registerRoute(
new RegExp("https://your.cdn.com/"),
workbox.strategies.staleWhileRevalidate()
);
workbox.routing.registerRoute(
new RegExp("https://your.img.cdn.com/"),
workbox.strategies.cacheFirst({
cacheName: "example:img",
})
);
通过
-
HTML,如果你想让页面离线可以访问,使用
NetworkFirst ,如果不需要离线访问,使用NetworkOnly ,其他策略均不建议对HTML 使用。 -
CSS 和JS ,情况比较复杂,因为一般站点的CSS ,JS 都在CDN 上,SW 并没有办法判断从CDN 上请求下来的资源是否正确(HTTP 200) ,如果缓存了失败的结果,问题就大了。这种我建议使用Stale-While-Revalidate 策略,既保证了页面速度,即便失败,用户刷新一下就更新了。如果你的CSS ,JS 与站点在同一个域下,并且文件名中带了Hash 版本号,那可以直接使用Cache First 策略。 -
图片建议使用
Cache First ,并设置一定的失效事件,请求一次就不会再变动了。
CLI
$ yarn global add workbox-cli
# 生成配置文件
$ workbox wizard

module.exports = {
globDirectory: "./",
globPatterns: ["**/*.{html,json,js}"],
swDest: "./src/sw.js",
};
基于配置文件可以快速生成
$ workbox generateSW path/to/config.js
预缓存
// 预缓存,同ws中的cacheName
workbox.core.setCacheNameDetails({
prefix: "sharee",
suffix: "v1",
precache: "precache",
runtime: "runtime",
});
// 动态缓存
workbox.routing.precacheAndRoute([
{
url: "/index.html",
revision: "asdf",
},
"/index.abc.js",
"/index.bcd.css",
]);
路由匹配& 请求响应
workbox.routing.registerRoute(match, handlerCb);
match:路由匹配规则
上述函数中的
- 对
URL 进行字符串匹配,绝对路径/ 相对路径
workbox.routing.registerRoute("http://127.0.0.1:8080/index.css", handlerCb);
workbox.routing.registerRoute("/index.css", handlerCb); // 以当前url为基准
workbox.routing.registerRoute("./index.css", handlerCb);
- 正则匹配
workbox.routing.registerRoute(`/\/index\.css$/`, handlerCb);
- 自定义匹配方法
该自定义方法是一个同步执行函数,在表示资源请求匹配成功时返回一个真值。
const match = ({ url, event }) => {
return url.pathname === "/index.html";
};
handlerCb:资源请求处理方法
对匹配到的资源请求进行处理的方法,开发者可以在这里决定如何响应请求,无论是从网络、从本地缓存还是在
// url:event.request.url 经 URL 类实例化的对象;
// event:fetch 事件回调参数;
// params:自定义路由匹配方法所返回的值。
const handlerCb = ({ url, event, params }) => {
return Promise.resolve(new Response("Hello World!"));
};
缓存策略
拦截请求后我们可能会缓存响应,通常我们需要自己来编写相应的策略,
- NetworkFirst:网络优先
- CacheFirst:缓存优先
- NetworkOnly:仅使用正常的网络请求
- CacheOnly:仅使用缓存中的资源
- StaleWhileRevalidate:从缓存中读取资源的同时发送网络请求更新本地缓存
以
workbox.routing.registerRoute(
/\.(jpe?g|png)/,
new workbox.strategies.CacheFirst({
cacheName: "image-runtime-cache",
plugins: [
// 通过插件来强化缓存策略
new workbox.expiration.Plugin({
maxAgeSeconds: 7 * 24 * 60 * 60, // 对图片资源缓存1星期
maxEntries: 10, // 匹配该策略的图片最多缓存10张
}),
],
fetchOptions: {
// 跨域请求的资源
mode: "cors",
},
})
);