您当前的位置:首页 > 电脑百科 > 网络技术 > 网络知识

Service Worker与缓存

时间:2019-09-02 10:44:03  来源:  作者:

前言

随着Service Worker(以下简称SW)的普及和规范,我们可以使用SW提供的缓存接口替代HTTP缓存。当然SW的功能是强大的,除了缓存功能,还能够使用它来实现离线、数据同步、后台编译等等。

Service Worker与缓存

 

应用

一个标配版的sw缓存工代代码应该有以下的片段:

const version = '2';
self.addEventListener('install', event => {
 event.waitUntil(
 caches.open(`static-${version}`)
 .then(cache => cache.addAll([
 '/styles.css',
 '/script.js'
 ]))
 );
});
self.addEventListener('fetch', event => {
 event.respondWith(
 caches.match(event.request)
 .then(response => response || fetch(event.request))
 );
});

首先你要明白的前提是,网络请求首先到达的是SW脚本中,如果未命中再转发给HTTP缓存。

这段代码的意思是,在SW的install阶段我们将script.js和styles.css放入缓存中;而在请求发起的fetch阶段,通过资源的URL去缓存内查找匹配,成功后立刻返回,否则走正常的网络请求流程。

但你有没有考虑过,在install阶段的资源内容是哪里来的?仍然是从HTTP缓存中。这样SW缓存机制又有可能随着HTTP缓存陷入了之前所说的版本不一致的困境中。

既然我们借助SW重写了缓存机制,所以也不想再受牵制于旧的HTTP缓存。解决办法是让SW中的请求必须向服务端验证:

self.addEventListener('install', event => {
 event.waitUntil(
 caches.open(`static-${version}`)
 .then(cache => cache.addAll([
 new Request('/styles.css', { cache: 'no-cache' }),
 new Request('/script.js', { cache: 'no-cache' })
 ]))
 );
});

目前并非所有的浏览器都支持cache选项的配置。但这个不是太大问题,我们可以通过添加随机数来保证每次请求的URL都不相同,间接的使得缓存失效:

self.addEventListener('install', event => {
 event.waitUntil(
 caches.open(`static-${version}`)
 .then(cache => Promise.all(
 [
 '/styles.css',
 '/script.js'
 ].map(url => {
 // cache-bust using a random query string
 return fetch(`${url}?${Math.random()}`).then(response => {
 // fail on 404, 500 etc
 if (!response.ok) throw Error('Not ok');
 return cache.put(url, response);
 })
 })
 ))
 );
});

上面的代码使用的是随机数作为文件版本,你当然可以使用更精确的方式,例如根据文件内容生成md5值来作为版本信息,而这个思维模式就是模块sw-precache模块的背后哲学。

sw-precache

想象一下现在我们需要实施上述绕过http缓存的解决方案。首先我们需要知道究竟站点中有多少静态资源,然后设定版本号的生成规则,接着根据静态资源再具体的编写我们的SW脚本。

不难看出,上面描述的过程可以是机械化自动化的,包括识别静态资源,生成SW脚本等。而类库sw-precache则可以帮我们完成这些工作。尤其是在构建阶段配合Gulp或者Grunt使用,具体用法我们可以摘录它官网的一段DEMO:

gulp.task('generate-service-worker', function(callback) {
 var swPrecache = require('sw-precache');
 var rootDir = 'App';
 swPrecache.write(`${rootDir}/service-worker.js`, {
 staticFileGlobs: [rootDir + '/**/*.{js,html,css,png,jpg,gif,svg,eot,ttf,woff}'],
 stripPrefix: rootDir
 }, callback);
});

这段脚本注册了一个名为generate-service-worker的任务,用于在根目录生成一个名为service-worker.js的sw脚本,而这个脚本缓存的资源呢,则是目录下的所有脚本、样式、图片、字体等几乎所有的静态文件。

浏览器的整体缓存机制

除了HTTP标准缓存以外,浏览器还有可能存在标准以外的缓存机制。对于Chrome浏览器而言还存在Memory Cache、Push “Cache”。一个请求在查找资源的过程中经过的缓存顺序是Memory Cache、Service Worker、HTTP Cache、Push “Cache”。HTTP Cache和Service Worker已经介绍过了,接下来简单介绍Memory Cache和Push Cache

Memory Cache

内存缓存”中主要包含的是当前文档中页面中已经抓取到的资源。例如页面上已经下载的样式、脚本、图片等。我们不排除页面可能会对这些资源再次发出请求,所以这些资源都暂存在内存中,当用户结束浏览网页并且关闭网页时,内存缓存的资源会被释放掉。

这其中最重要的缓存资源其实是preloader相关指令(例如<link rel="prefetch">)下载的资源。总所周知preloader的相关指令已经是页面优化的常见手段之一,而通过这些指令下载的资源也都会暂存到内存中。根据一些材料,如果资源已经存在于缓存中,则可能不会再进行preload。

需要注意的事情是,内存缓存在缓存资源时并不关心返回资源的HTTP缓存头Cache-Control是什么值,同时资源的匹配也并非仅仅是对URL做匹配,还可能会对Content-Type,CORS等其他特征做校验

Push “Cache”

“推送缓存”是针对HTTP/2标准下的推送资源设定的。推送缓存是session级别的,如果用户的session结束则资源被释放;即使URL相同但处于不同的session中也不会发生匹配。推送缓存的存储时间较短,在Chromium浏览器中只有5分钟左右,同时它也并非严格执行HTTP头中的缓存指令

Push “Cache”的优缺点

关于推送缓存,主要有以下几大特点:

  • 几乎所有的资源都能被推送,并且能够被缓存。测试过程是作者在推送资源之后尝试用fetch()、XMLHttpRequest、<link rel="stylesheet" href="…">、<script src="…">、<iframe src="…">获取推送的资源。Edge和Safari浏览器支持相对比较差
  • no-cache和no-store资源也能被推送
  • Push Cache是最后一道缓存机制(之前会经过Memory Cache、HTTP Cache、Service Worker)
  • 如果连接被关闭则Push Cache被释放
  • 多个页面可以使用同一个HTTP/2的连接,也就可以使用同一个Push Cache。这主要还是依赖浏览器的实现而定,出于对性能的考虑有的浏览器会对相同域名但不同的tab标签使用同一个HTTP连接。
  • 一旦Push Cache中的资源被使用即被移除如果Push Cache或者HTTP Cache已经存在被推送的资源,则有可能浏览器拒绝推送
  • 你可以为其他域名推送资源


Tags:Service Worker   点击:()  评论:()
声明:本站部分内容及图片来自互联网,转载是出于传递更多信息之目的,内容观点仅代表作者本人,如有任何标注错误或版权侵犯请与我们联系(Email:2595517585@qq.com),我们将及时更正、删除,谢谢。
▌相关推荐
前言随着Service Worker(以下简称SW)的普及和规范,我们可以使用SW提供的缓存接口替代HTTP缓存。当然SW的功能是强大的,除了缓存功能,还能够使用它来实现离线、数据同步、后台编译...【详细内容】
2019-09-02  Tags: Service Worker  点击:(230)  评论:(0)  加入收藏
▌简易百科推荐
以京训钉开发平台接口文档为例,使用HttpClient类请求调用其接口,对数据进行增删改查等操作。 文档地址: https://www.yuque.com/bjjnts/jxd/bo1oszusing System;using System.C...【详细内容】
2021-12-28  Wednes    Tags:HttpClient   点击:(1)  评论:(0)  加入收藏
阿里云与爱快路由安装组网教程一、开通好阿里云轻量服务器之后在服务器运维-远程连接处进行远程 二、进入控制台后在root权限下根据需要安装的固件位数复制下面命令。32位:wg...【详细内容】
2021-12-28  ikuai    Tags:组网   点击:(1)  评论:(0)  加入收藏
HTTP 报文是在应用程序之间发送的数据块,这些数据块将通过以文本形式的元信息开头,用于 HTTP 协议交互。请求端(客户端)的 HTTP 报文叫做请求报文,响应端(服务器端)的叫做响应...【详细内容】
2021-12-27  程序员蛋蛋    Tags:HTTP 报文   点击:(5)  评论:(0)  加入收藏
一 网络概念:1.带宽: 标识网卡的最大传输速率,单位为 b/s,比如 1Gbps,10Gbps,相当于马路多宽2.吞吐量: 单位时间内传输数据量大小单位为 b/s 或 B/s ,吞吐量/带宽,就是网络的使用率...【详细内容】
2021-12-27  码农世界    Tags:网络   点击:(3)  评论:(0)  加入收藏
1.TCP/IP 网络模型有几层?分别有什么用? TCP/IP网络模型总共有五层 1.应用层:我们能接触到的就是应用层了,手机,电脑这些这些设备都属于应用层。 2.传输层:就是为应用层提供网络...【详细内容】
2021-12-22  憨猪哥08    Tags:TCP/IP   点击:(35)  评论:(0)  加入收藏
TCP握手的时候维护的队列 半连接队列(SYN队列) 全连接队列(accepted队列)半连接队列是什么?服务器收到客户端SYN数据包后,Linux内核会把该连接存储到半连接队列中,并响应SYN+ACK报...【详细内容】
2021-12-21  DifferentJava    Tags:TCP   点击:(10)  评论:(0)  加入收藏
你好,这里是科技前哨。 随着“元宇宙”概念的爆火,下一代互联网即将到来,也成了互联网前沿热议的话题,12月9日美国众议院的听证会上,共和党议员Patrick McHenry甚至宣称,要调整现...【详细内容】
2021-12-17  王煜全    Tags:Web3   点击:(14)  评论:(0)  加入收藏
一、demopublic static void main(String[] args) throws Exception { RetryPolicy retryPolicy = new ExponentialBackoffRetry( 1000, 3);...【详细内容】
2021-12-15  程序员阿龙    Tags:Curator   点击:(22)  评论:(0)  加入收藏
一、计算机网络概述 1.1 计算机网络的分类按照网络的作用范围:广域网(WAN)、城域网(MAN)、局域网(LAN);按照网络使用者:公用网络、专用网络。1.2 计算机网络的层次结构 TCP/IP四层模...【详细内容】
2021-12-14  一口Linux    Tags:网络知识   点击:(31)  评论:(0)  加入收藏
无论是在外面还是在家里,许多人都习惯了用手机连接 WiFi 进行上网。不知道大家有没有遇到过这样一种情况, 明明已经显示成功连接 WiFi,却仍然提示“网络不可用”或“不可上网”...【详细内容】
2021-12-14  UGREEN绿联    Tags:WiFi   点击:(25)  评论:(0)  加入收藏
相关文章
    无相关信息
最新更新
栏目热门
栏目头条