持续更新中…
注册 ServiceWorker
将网站根目录下的 serviceWorker.js 文件注册为 ServiceWorker。
尽量保证 serviceWorker.js 文件在网站根目录,这样才能监听整个网站的请求
1 2 3 4 5 6 7 8 9 10 11 12 13
| if ("serviceWorker" in navigator) { navigator.serviceWorker .register("/serviceWorker.js", { scope: "/", }) .then((registration) => { console.log("ServiceWorker registration successful"); }) .catch((err) => { console.warn("ServiceWorker registration failed: ", err); }); }
|
编写 ServiceWorker
静态资源一般作为网站的骨架,包括通用的样式、字体、图片等,一般不会有太大变化,所以可以作为长期缓存缓存到本地浏览器。
长期缓存的文件会永久的存在于本地,如果出现了静态资源的更新,可在浏览器中使用 ctrl + F5 组合键来强制清除缓存
缓存静态资源
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
|
const CACHE_STATIC_NAME = "blog_static_cache";
const staticUrls = [ "/index.html", ];
self.addEventListener("install", (ev) => { console.log("ServiceWorker install"); ev.waitUntil( caches.open(CACHE_STATIC_NAME).then((cache) => { return cache.addAll(staticUrls); }) ); });
self.addEventListener("fetch", (ev) => { ev.respondWith( caches.match(ev.request).then((cacheResponse) => { if (cacheResponse) return cacheResponse; return fetch(ev.request); }) ); });
|
添加动态资源缓存
这里的动态资源特指变化周期很短的资源,但即使是变化很快的动态资源,如果它很大,也会影响到页面的加载速度,
所以可以将动态资源缓存到内存中,自定义一个较短的过期时间,过期后重新缓存。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118
|
const CACHE_STATIC_NAME = "blog_static_cache";
const CACHE_NAME = "blog_cache";
const staticUrls = [ "/index.html", ];
const dynamicUrls = new Map();
function isCacheExpired(req, parameter = {}) { let neededParms = Object.assign( {}, { timeout: 8 * 3600, }, parameter );
let expired = true; let prevTimestamp = dynamicUrls.get(req.url);
if (prevTimestamp) { let currentTimestamp = Date.now(); let flag = currentTimestamp > prevTimestamp + neededParms.timeout * 1000; expired = flag; } else { expired = true; } return Promise.resolve(expired); }
function isUrlStaticCache(url, staticUrls) { let find = staticUrls.find((staticUrl) => { return encodeURIComponent(url).includes(encodeURIComponent(staticUrl)); }); if (find) return true; return false; }
function isUrlCurrentOrigin(url) { return url.includes(self.location.origin); }
self.addEventListener("install", (ev) => { console.log("ServiceWorker install"); ev.waitUntil( caches.open(CACHE_STATIC_NAME).then((cache) => { return cache.addAll(staticUrls); }) ); });
self.addEventListener("fetch", (ev) => { ev.respondWith( caches.match(ev.request).then(async (cacheResponse) => { if (cacheResponse) { if (isUrlStaticCache(ev.request.url, staticUrls)) return cacheResponse; else { let expired = await isCacheExpired(ev.request); if (expired) { let response = await fetch(ev.request); const responseClone = response.clone(); let cache = await caches.open(CACHE_NAME); cache.put(ev.request, responseClone); dynamicUrls.set(ev.request.url, Date.now()); return response; } else { return cacheResponse; } } }
else { if (isUrlCurrentOrigin(ev.request.url)) { let response = await fetch(ev.request); const responseClone = response.clone(); let cache = await caches.open(CACHE_NAME); cache.put(ev.request, responseClone); dynamicUrls.set(ev.request.url, Date.now()); return response; } else { return fetch(ev.request); } } }) ); });
|