为了优化性能,使用缓存是一种比较常见的手段。那么如何实现缓存以及如何避免缓存呢,都是要探讨的话题。能够从三个部分:http 缓存、cookie、localStorage&sessionStorage 来重点讲述缓存实现的原理、过程以及实现的方式。因为篇幅缘由,本篇重点讲述 http 缓存。css
缓存命中: 使用已有的副本为到达的请求提供资源而不用从服务器中获取资源。
缓存未命中: 达缓存的请求没有副本可用,而被转发给原始服务器,与缓存命中相反。
CHP: Cache Hit Percentage,缓存提供服务请求所占有的比例,缓存的文件个数/请求资源个数。
下图是打开百度资源后所请求的资源(部分)状况:html
能够看到其中有两个资源是从服务器中获取的,其他是从缓存中获取,那么其CHP值为:80%。web
所谓的强缓存是指请求资源的时候不须要发送 http 向服务器发送请求,直接从客户端获取资源。实现的方式是有 http 的 Expires,Cache-Control两个response header实现的。ajax
Expires是 http 1.0 提出的一个 header,其值是一个资源有效期的绝对时间,实现缓存的过程以下: express
Expires的值为一个绝对时间,当客户端改变了时间或者时区问题,会致使缓存失效;所以在http 1.1 中引入了Cache-Control。浏览器
Cache-Control与Expires同时存在的时候Cache-Control的优先级大于Expires缓存
Cache-Control 实现的过程与 Expires 相似,其常见的有三个值: 服务器
Cache-Control:max-ag=0 与 Cache-Control:no-cache 在使用效果上没有多大的区别,区别在于服务器挂了是否可使用以前的缓存的response 即 max-age=0 能够看到以前缓存的内容,页面正常显示以前的内容而 no-cache 则返回错误5xx状态码cookie
上面讲述利用Expires与Cache-Control如何实现缓存的,那怎么样在请求资源的时候加入这两个header呢,有如下两种方式:
(1) 经过代码的方式,在web服务器返回的响应中添加响应头部,如在 Express 框架中使用 setHeader 加入,代码以下:session
const picMap = { 'logo.png': 'no-store', 'avatar.png': 'no-cache', 'background.png': 'max-age: 36000' } app.use(express.static(publicPath, setHeaders(res, filePath, stat) { let baseName = path.basename(filePath); picMap[baseName] && res.set('Cache-Control', picMap[baseName]) }));
(2) 经过配置web服务器的方式,在服务器配置文件中加入 Expires 与 Cache-Control,进行统一配置。
协商缓存是在用户强缓存失败的状况下,向服务器端进行再验证。它与强缓存的区别在于会向服务器发送请求,可是不会获取资源,浏览器端请求的资源仍是从缓存中获取。其实现有两对首部:【Last-Modified,If-Modified-Since】、【ETag、If-None-Match】其中以【Last-Modified,If-Modified-Since】为例,讲解实现的过程。
开发侧
(1) 给资源加上一个动态的参数,如css/index.css?v=0.1
(2) 若是缓存问题出如今 ajax 请求中,能够给请求地址添加随机数;
用户侧
(1) F5:cache-control:max-age=0
(2) Ctrl+F5:请求的时候不带上任何缓存头
参考文献
[1] 《http权威指南》。
[2] https://www.cnblogs.com/lyzg/...