CDN缓存
CDN(Content DeliveryNetwork),即内容分发网络。CDN是构建在网络之上的内容分发网络,依靠部署在各地的边缘服务器,通过中心平台的负载均衡、内容分发、调度等功能模块,使用户就近获取所需内容,降低网络拥塞,提高用户访问响应速度和命中率
具体是什么意思呢? 当我们使用CDN时,CDN会优先调度离我们最近的边缘服务器并检测是否有该请求的缓存数据,如果有则返回缓存数据;如果没有则向中心服务器请求并返回。
优点:
- 减少带宽的占用,减轻网络拥堵,提高访问速度
- 减轻本地服务器负担
DNS缓存
DNS(Domin Name System)是域名和IP相互映射的分布式数据库,可将域名解析成供计算机识别的IP地址
DNS查询耗时大约20ms,在DNS查询过程中,浏览器不进行任何活动,会导致浏览器出现空白页;如果DNS查询很多,会导致网页加载性能受到影响
DNS缓存机制: 当首次访问一个域名,通过DNS解析获取其IP,并将域名及对应的IP缓存下来,当下次访问该域名时,则不再进行DNS查询,直接使用缓存下来的IP
缓存时间: 不同的浏览器DNS缓存时间也不同,IE默认的DNS缓存时间为30min,Firfox、Chrome默认的DNS缓存时间为1min
若域名对应的ip已更改,则需要清除DNS缓存(ipconfig/flushdns)
HTTP缓存
当客户端第一次完成数据请求后,浏览器会缓存本次请求的数据,当下次执行相同请求,则直接在缓存数据库中返回;但HTTP缓存有多种规则,根据是否向服务器发送请求分为 “强制缓存” 和 “对比缓存” 两种
强制缓存
当客户端发送请求时,若浏览器中有该请求的缓存数据,则直接返回缓存数据;
若浏览器中未有本次请求的缓存数据或缓存数据过期,则本次请求会抵达服务器去请求数据;
那么如何去判断缓存数据是否已经失效(过期)呢?
当客户端与服务器完成一次请求后,服务器会在Response Headers 报文中返回缓存规则信息;在Response Body报文中返回响应的数据;缓存规则有 Expires 和 Cache-Control 两种
Expires
Expires表示缓存数据的到期时间,若下次请求的日期小于到期时间,则直接从缓存数据中读取;若大于到期时间,则直接请求服务器
- 由于到期时间是有服务器端生成的,这与客户端的时间会有偏差,所以从HTTP 1.1 版本后此方案由 Cache-Control 代替
Cache-Control
目前HTTP标准的缓存规则,包含“private”、“public”,“max-age=”、“no-cache”、“no-store”
- private:客户端可以缓存
- public:客户端和服务端都可以缓存
- max-age=xxx:缓存的总时长,单位为秒
- no-cache:使用对比缓存验证缓存数据
- no-store:不适用强制缓存和对比缓存
对比缓存
浏览器完成一次完整请求后,服务器返回数据和缓存规则,客户端收到并缓存在缓存数据库中;
对比缓存顾名思义就是每次请求,客户端都会拿缓存标识去服务器判断该缓存是否可用,若可用,服务器返回304并通知客户端从缓存中读取,若不可用则服务器返回200和最新的数据和缓存规则
缓存标识分为以下两种
Last-Modified / If-Modified-Since
服务器返回资源最后一次修改的时间 再次请求时,客户端在请求头携带If-Modified-Since;服务器拿If-Modified-Since与资源最后修改时间做对比,若大于或等于,则命中对比缓存,返回304,从缓存中读取;反之,则服务器返回最新的数据和缓存规则,并返回200Etag / If-None-Match(优先级高于Last-Modified / If-Modified-Since)
第一次请求,浏览器返回资源唯一标识(一般都是hash生成的)服务器存储着文件的Etag字段,可以在与每次客户端传送If-no-match的字段进行比较。如果相等,则表示未修改,响应304;反之,则表示已修改,响应200状态码,返回数据。
Service Worker 离线缓存
Service Worker能够充当网络代理服务器的功能,能拦截网络请求(fetch)、离线缓存
- Service Worker是运行在worker上下文,所以不能访问DOM
- 运行在其他线程中,不会造成拥堵,完全异步,因此同步API不可使用
- 只能在https或本地localhost上运行
- 注册serviceWorker
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>serviceWorker</title>
<script type="text/javascript">
if ('serviceWorker' in navigator) {
navigator.serviceWorker.register('./serviceWorker.js', {scope: './'})
.then(registration => {
console.log('注册成功', registration.scope)
})
.catch(err => {
console.log('注册失败', err)
})
}
</script>
</head>
<body>
</body>
复制代码
- ServiceWorker.js
let self = this;
// 完成serviceWorker的注册与缓存文件
self.addEventListener('install', function (event) {
event.waitUntil(
caches.open('v1').then(function (cache) {
return cache.addAll([
'./index.html' //缓存文件
])
})
)
})
// 监听拦截http请求,做资源缓存
self.addEventListener('fetch', function (event) {
event.responseWith(
// 在缓存中匹配请求
caches.match(event.request)
.then(function (response) {
// 若缓存存在,则直接返回
if (response) {
return response
}
// 拷贝request副本
let fetchRequest = event.request.clone()
// 未命中缓存,发起网络请求
return fetch(fetchRequest).then(function (response) {
// 判断是否请求成功
if (!response || response.status != 200 || response.type != 'basic') {
return response
}
// 缓存请求和响应数据
let fetchResponse = response.clone()
caches.open('v1').then(function (cache) {
cache.put(event.request, fetchResponse)
})
// 返回真实的网络请求数据
return response
})
})
)
})
复制代码
mainfest
html5引入的新标准,可以离线缓存静态文件
优点
- 离线浏览
- 已缓存资源加载速度更快
- 减轻服务器负载 - 只需从服务器中获取更新或修改过的资源
步骤
- 新建一个后缀为'manifest.appcache'的文件,文件内容如下
CACHE MANIFEST // 首次完成请求后进行缓存,离线可访问 manifest.css NETWORK: // 每次请求都需要网络,不缓存 network.css FALLBACK: // 页面无法连接网络时显示的页面 404.html 复制代码
- 在中加入manifest属性并指定文件所在地址
<html manifest="manifest.appcache"> 复制代码
首次访问,请求静态文件
再次访问,manifest.css已被缓存
当离线后,network.css无法访问,但仍能从缓存中读取manifest.css