代码已经关联到github: 链接地址 文章有更新也会优先在这,觉得不错可以顺手点个star,这里会持续分享自己的开发经验(:
浏览器再次发送请求时:
强缓存主要由响应消息头 Cache-Control
和 Expires
两个 Header
决定的,在一定时间内不向后端请求,直接使用内存或者磁盘内的缓存内容,前者的优先级更高。
Cache-Control: max-age=31536000 //缓存时间 | no-store:禁止本地缓存 | no-cache:本地缓存,但是强制每次请求直接发送给源服务器,由服务器判断是否使用缓存
Cache-Control: private;max-age=31536000 //默认是public 允许代理
Expires: Wed, 21 Oct 2020 07:28:00 GMT //该时间之后请求过期 Cache-control 优先级比 Expires 优先级高
注意请求头的消息头也可以设置
Cache-Control
, 表示客户端想要的缓存策略是什么。
一般不经常变动的JS和CSS均会有一个很大的过期时间,搭配上版本号进行缓存策略,减少向后端的请求,如果均不设置只带版本号也可以,因为浏览器自动有缓存的策略。
有些时候,我们会看到Cache-Control: max-age=31536000
,那么浏览器帧的会缓存这个数据到一年吗,答案当然是否定的,设置这个值只是因为它是协议允许的最大值,浏览器不会缓存那么久,当缓存满了会优先删除旧的内容,但是CDN会,这样可以减少服务器的压力。
由 If-none-match/ETags
和 If-Modified-Since/Last-Modified
参数决定,通常在强缓存失效后,向服务端通信,服务端确定是否使用缓存,前者优先级更高。
ETags
是服务器资源的一个唯一标识,请求响应时消息头会带上这个唯一标识,请求头带上上次请求返回的etag(If-none-match
),由服务器判断资源是否改变。Last-Modified
),请求时消息头会带上这个修改时间(If-Modified-Since
),由服务器判断资源是否改变。对于频繁变动的资源,服务器端需设置Cache-Control: no-cache
使浏览器每次都请求服务器,且增加返回请求头 ETag 或者 Last-Modified 来验证资源是否有效。这样的做法虽然不能节省请求数量,但是能显著减少响应数据大小。
URL
后面(通常是文件名后面)会加上版本号。一个服务器与浏览器之间的中间人角色,如果网站中注册了service worker那么它可以拦截当前网站所有的请求,进行判断(需要编写相应的判断程序),如果需要向服务器发起请求的就转给服务器,如果可以直接使用缓存的就直接返回缓存不再转给服务器。
Service Worker是浏览器在后台独立于网页运行的、用JavaScript编写的脚本。
让我们来看看最小的Service Worker长什么样,以及怎么跑起来:
// 不起眼的一行if,除了防止报错之外,也无意间解释了PWA的P:
// 如果浏览器不支持Service Worker,那就当什么都没有发生过
if ('serviceWorker' in navigator) {
window.addEventListener('load', function () {
// 所以Service Worker只是一个挂在navigator对象上的HTML5 API而已
// scope 参数是可选的,可以用来指定你想让 service worker 控制的内容的子目录。 在这个例子里,我们指定了 '/',表示 根网域下的所有内容。这也是默认值。
navigator.serviceWorker.register('/service-worker.js', {scope: './'}).then(function (registration) {
console.log('我注册成功了');
}, function (err) {
console.log('我注册失败了');
});
});
}
复制代码以上代码,在load事件触发后,下载并注册了service-worker.js这个文件,Service Worker的逻辑,就写在这里:
// service-worker.js
// 虽然可以在里边为所欲为地写任何js代码,或者也可以什么都不写,
// 都不妨碍这是一个Service Worker,但还是举一个微小的例子:
//监听安装事件,install 事件一般是被用来设置你的浏览器的离线缓存逻辑
this.addEventListener('install', function(event) {
//通过这个方法可以防止缓存未完成,就关闭serviceWorker
event.waitUntil(
//caches api: https://developer.mozilla.org/zh-CN/docs/Web/API/CacheStorage
caches.open('v1').then(function(cache) {
//指定要缓存的内容,地址为相对于跟域名的访问路径
return cache.addAll([
'/sw-test/',
'/sw-test/index.html',
'/sw-test/style.css',
'/sw-test/app.js',
'/sw-test/image-list.js',
'/sw-test/star-wars-logo.jpg',
'/sw-test/gallery/bountyHunters.jpg',
'/sw-test/gallery/myLittleVader.jpg',
'/sw-test/gallery/snowTroopers.jpg'
]);
})
);
});
//监听fetch,拦截请求
this.addEventListener('fetch', function(event) {
var response;
event.respondWith(
caches.match(event.request).then(function(response) {
if (response) {
console.log('Found response in cache:', response);
return response;
}
console.log('No response found in cache. About to fetch from network...');
return fetch(event.request).then(function(response) {
console.log('Response from network is:', response);
caches.open('v1').then(function(cache) {
cache.put(event.request, response);
});
return response.clone();
}).catch(function(error) {
console.error('Fetching failed:', error);
throw error;
});
})
);
});
详细见:Service Worker 从入门到出门
缓存主要有4种:Service Worker
、Memory Cache
、 Disk Cache
和 Push Cache
Service Worker 从入门到出门
浏览器帧的会缓存一年吗
有DNS的地方,就有缓存。浏览器、操作系统、Local DNS、根域名服务器,它们都会对DNS结果做一定程度的缓存:
在浏览器本地缓存失效后,浏览器会向CDN边缘节点发起请求。类似浏览器缓存,CDN边缘节点也存在着一套缓存机制。CDN边缘节点缓存策略因服务商不同而不同,但一般都会遵循http标准协议,通过http响应头中的Cache-control
判断资源是否过期
其优势是: