美文网首页
3.7.1 使用 Service Workers 实现离线缓存

3.7.1 使用 Service Workers 实现离线缓存

作者: 柠檬与断章 | 来源:发表于2019-11-28 09:39 被阅读0次

3.7.1 使用 Service Workers 实现离线缓存

问题一:使用 Service Workers 实现离线缓存?

Service Workers 在注册成功后会在其生命周期中派发出一些事件,通过监听对应的事件在特点的时间节点上做一些事情。

在 Service Workers 脚本中,引入了新的关键字self代表当前的 Service Workers 实例。

在 Service Workers 安装成功后会派发出install事件,需要在这个事件中执行缓存资源的逻辑,实现代码如下:

// 当前缓存版本的唯一标识符,用当前时间代替var cacheKey=newDate().toISOString();// 需要被缓存的文件的 URL 列表var cacheFileList=['/index.html','/app.js','/app.css'];// 监听 install 事件self.addEventListener('install',function(event){// 等待所有资源缓存完成时,才可以进行下一步event.waitUntil(caches.open(cacheKey).then(function(cache){// 要缓存的文件 URL 列表returncache.addAll(cacheFileList);}));});

接下来需要监听网络请求事件去拦截请求,复用缓存,代码如下:

self.addEventListener('fetch',function(event){event.respondWith(// 去缓存中查询对应的请求caches.match(event.request).then(function(response){// 如果命中本地缓存,就直接返回本地的资源if(response){returnresponse;}// 否则就去用 fetch 下载资源returnfetch(event.request);}));});

以上就实现了离线缓存。

问题二:如何更新缓存?

线上的代码有时需要更新和重新发布,如果这个文件被离线缓存了,那就需要 Service Workers 脚本中有对应的逻辑去更新缓存。 这可以通过更新 Service Workers 脚本文件做到。

浏览器针对 Service Workers 有如下机制:

每次打开接入了 Service Workers 的网页时,浏览器都会去重新下载 Service Workers 脚本文件(所以要注意该脚本文件不能太大),如果发现和当前已经注册过的文件存在字节差异,就将其视为“新服务工作线程”。

新 Service Workers 线程将会启动,且将会触发其 install 事件。

当网站上当前打开的页面关闭时,旧 Service Workers 线程将会被终止,新 Service Workers 线程将会取得控制权。

新 Service Workers 线程取得控制权后,将会触发其 activate 事件。

新 Service Workers 线程中的 activate 事件就是最佳的清理旧缓存的时间点,代码如下:

// 当前缓存白名单,在新脚本的 install 事件里将使用白名单里的 key var cacheWhitelist=[cacheKey];self.addEventListener('activate',function(event){event.waitUntil(caches.keys().then(function(cacheNames){returnPromise.all(cacheNames.map(function(cacheName){// 不在白名单的缓存全部清理掉if(cacheWhitelist.indexOf(cacheName)===-1){// 删除缓存returncaches.delete(cacheName);}}));}));});

最终完整的代码 Service Workers 脚本代码如下:

// 当前缓存版本的唯一标识符,用当前时间代替var cacheKey=newDate().toISOString();// 当前缓存白名单,在新脚本的 install 事件里将使用白名单里的 keyvar cacheWhitelist=[cacheKey];// 需要被缓存的文件的 URL 列表var cacheFileList=['/index.html','app.js','app.css'];// 监听 install 事件self.addEventListener('install',function(event){// 等待所有资源缓存完成时,才可以进行下一步event.waitUntil(caches.open(cacheKey).then(function(cache){// 要缓存的文件 URL 列表returncache.addAll(cacheFileList);}));});// 拦截网络请求self.addEventListener('fetch',function(event){event.respondWith(// 去缓存中查询对应的请求caches.match(event.request).then(function(response){// 如果命中本地缓存,就直接返回本地的资源if(response){returnresponse;}// 否则就去用 fetch 下载资源returnfetch(event.request);}));});// 新 Service Workers 线程取得控制权后,将会触发其 activate 事件self.addEventListener('activate',function(event){event.waitUntil(caches.keys().then(function(cacheNames){returnPromise.all(cacheNames.map(function(cacheName){// 不在白名单的缓存全部清理掉if(cacheWhitelist.indexOf(cacheName)===-1){// 删除缓存returncaches.delete(cacheName);}}));}));});

相关文章

网友评论

      本文标题:3.7.1 使用 Service Workers 实现离线缓存

      本文链接:https://www.haomeiwen.com/subject/enuxictx.html