为什么要有缓存机制?
每个网站的html、静态资源(包括图片、css、js)都不经常变化,如若每次进入网站都会全部请求,试想有必要吗?能不能按需请求呢,比如有更新了再重新请求?或者无痕浏览时?
无论是提出的哪种假设,都不是前端可以独立完成的,需要交互做到,那么cookie就用到了。
好处有哪些呢?
- 提高首屏加载速度
- 可以减少客户端流量消耗
- 减少服务器压力
缓存策略有哪几种?
当我们第一次请求服务器的时候,服务器便会返回资源并决定是否缓存以及缓存规则。下次在请求的时候,则会直接先去询问浏览器时候有可用缓存。若没有,则去请求服务器,并再将请求结果和缓存标识放入到浏览器缓存中。
强缓存
不向服务端去请求资源,而是直接在浏览器中获取资源
当浏览器向服务器发送请求的时候,服务器会将缓存规则放入HTTP响应的报文的HTTP头中和请求结果一起返回给浏览器,控制强制缓存的字段分别是Expires和Cache-Control,其中Cache-Conctrol的优先级比Expires高。
示例响应头中Cache-Control字段,赋值max-age为100s,也就是缓存有效时间100s(还有诸多类似max-age的字段不一一介绍)
借鉴过来的字段
(1)public:所有内容都将被缓存(客户端和代理服务器都可缓存)
(2)private:所有内容只有客户端可以缓存,Cache-Control的默认取值
(3)no-cache:客户端缓存内容,但是是否使用缓存则需要经过协商缓存来验证决定
(4)no-store:所有内容都不会被缓存,即不使用强制缓存,也不使用协商缓存
(5)max-age=xxx (xxx is numeric):缓存内容将在xxx秒后失效
响应头还有一个expires制定所获取资源的过期时间,优先度小于上者
const http = require('http')
const fs = require('fs')
http.createServer(function (request, response) {
if (request.url === '/test') {
response.writeHead(200, {
'Content-Type': 'text/javascript',
'Cache-Control': 'max-age=100' // 浏览器缓存时间,单位秒
})
response.end('kenny is so handsome')
}
}).listen(3000)
协商缓存
协商缓存就是强制缓存失效后,浏览器携带缓存标识向服务器发起请求,由服务器根据缓存标识决定是否使用缓存的过程,主要有以下两种情况
-
- 协商缓存成功返回304
- 失效,返回200
字段:last-modified与Etag(Etag优先级高)
Etag作用与,客户端请求资源时会携带上次响应头中的该字段值,服务端每个文件都有独立标示,如果该文件变动过则标示重新生成。如果这时客户端的请求文件包括改动过的文件,比较Etag不一致,则重新返回资源,否则使用缓存
last-modified客户端请求资源时会携带上次响应头中的该字段值,服务端接受到后比较决定是否重新返回资源
缓存位置在?
浏览器可以在内存、硬盘中开辟一个空间用于保存请求资源副本。
调试时在 DevTools Network 里看到 Memory Cache(內存缓存)和 Disk Cache(硬盘缓存),指的就是缓存所在的位置。请求一个资源时,会按照优先级(Service Worker -> Memory Cache -> Disk Cache -> Push Cache)依次查找缓存,如果命中则使用缓存,否则发起请求。
窍门:每个请求可以看到size的参数,也就是其大小,二次刷新后变成字符串的就是存储的位置
总结
强缓存生效直接使用缓存,强缓存失效使用协商缓存,协商缓存生效使用本地缓存,协商缓存失效则重新请求资源,并且存粗缓存与标识