浏览器缓存
好处:
- 减少冗余的数据传输,节省带宽。
- 减轻服务器的请求压力,因为有缓存可以减少向服务器发送请求,
- 资源从缓存中读取,加快客户端的访问速度。因为无需从服务器请求等待响应
缺点:
- 系统更新时,如何删除浏览器的缓存资源,加载最新的页面。
缓存
-
Service Worker:是一种独立于主线程之外的 Javascript 线程。它脱离于浏览器窗体,可以帮我们实现离线缓存、消息推送和网络代理等功能。
-
Memory Cache:存在内存中的缓存。包括当前中页面中已经抓取到的资源,例如页面上已经下载的样式、脚本、图片等。因为存储在内存中,MemoryCache 是响应速度最快的一种缓存,但由于同样的原因,缓存持续性很短,会随着进程的释放而释放,一旦我们关闭 Tab 页面,内存中的缓存也就被释放了。
-
Disk Cache:Disk Cache 也就是存储在硬盘中的缓存,读取速度慢点,但是什么都能存储到磁盘中,比之 Memory Cache 胜在容量和存储时效性上。会根据 HTTP Herder 中的字段判断哪些资源需要缓存,哪些资源可以不请求直接使用,哪些资源已经过期需要重新请求。
-
Push Cache:Push Cache 是 HTTP2 在 server push 阶段存在的缓存,当以上三种缓存都没有命中时,它才会被使用,Push Cache 是一种存在于会话阶段的缓存,当 session 终止时,缓存也随之释放。不同的页面只要共享了同一个 HTTP2 连接,那么它们就可以共享同一个 Push Cache。
强缓存
不会向服务器发送请求,直接从缓存中读取资源。状态码 200,显示 from disk cache 或 from memory cache。设置两种 Http Header 实现:Expires 和 Cache-Control
- Expires:值是一个时间戳,表示本地时间到这个设置的时间缓存就失效。
- 缺点:受限于本地时间
- 推荐使用 Cache-Control
- Cache-Control:优先级比 Expires 高,可以在请求头或者响应头中设置
- private:默认:只能在浏览器中缓存,只有在第一次请求中访问服务器。如有 max-age:缓存期间不访问服务器
- public:可以被任何缓存区缓存,如浏览器、服务器、代理服务器
- no-cache: 可以缓存,相当于协商缓存,每次都需要去服务器验证缓存是否一致。如有 max-age:缓存期间不访问服务器
- no-store:不仅不能缓存,连暂存也不可以
- max-age:以秒为单位的缓存时间,设置时间内,均使用本地的缓存,不再向服务器发起请求
- s-magage=:跟 max-age 作用一样,只在代理服务器中生效。优先级高于 max-age,只对 public 缓存有效,
- must-revalidate:可缓存但必须再想源服务器进行确认
- proxy-revalidate:要求中间缓存服务器对缓存的响应有效性进行确认
协商缓存
当 cache-control 和 Expires 过期或者它的属性设置为 no-cache 时,那么浏览器第二次请求时就会与服务器进行协商,判断资源是否更改,
-
没更改返回 304 Not Modified,使用本地缓存资源。
-
资源更改,返回 200,重新加载,本次缓存资源更新。
浏览器与服务器的交互依靠 Last-Modified/If-Modified-Since、ETag/If-None-Match 的 header 头属性,在请求头和响应头成对出现的。
- Last-Modified/If-Modified-Since:
浏览器在第一次访问资源,或缓存过期后访问,服务器返回资源的同时,在 response header 中添加 Last-Modified 的 header,值是这个资源在服务器上的最后修改时间,浏览器接收缓存文件和 header 信息。随后我们每次请求时,浏览器会自动带上一个叫 If-Modified-Since 的时间戳字段给服务器,它的值正是上一次 response 返回给它的 Last-modified 值,然后服务器会根据 If-Modified-Since 的值对比资源的最后修改时间判断资源是否进行了修改更新。
- ETag/If-None-Match :
Etag 是由服务器为每个资源生成的唯一的标识字符串,这个标识字符串是基于文件内容编码的,只要文件内容不同,它们对应的 Etag 就是不同的,因此 Etag 能够精准地感知文件的变化。Etag 和 Last-Modified 类似,当首次请求时,我们会在响应头里获取到一个最初的标识符字符串。那么下一次请求时,浏览器就会在请求头里就会带上一个值相同的、名为 if-None-Match 的字符串供服务器比对。Etag 的优先级会比 Last-Modified 高,但是 Etag 因为要生成,也会更消耗服务器性能。
Cache-Control: no-cache 和 Cache-Control: no-store 区别
看字面意思容易误解,no-cache 就是不缓存,但是 no-cache 并不是不缓存,而是使用协商缓存,所以并不能禁止缓存,no-store 才是真正的禁止缓存。从节省带宽角度讲,使用 no-cache 更优一点,文件未发生改变时只传输很小的报文大小,只有在文件改变时才会传输整个文件大小。而不是 no-store 不管什么情况都传输整个文件大小。
Pragma: no-cache:和 Cache-Control: no-cache 区别
Pragma: no-cache 跟 Cache-Control: no-cache 相同,Pragma: no-cache 兼容 http 1.0 ,Cache-Control: no-cache 是 http 1.1 提供的。因此,Pragma: no-cache 可以应用到 http 1.0 和 http 1.1,而 Cache-Control: no-cache 只能应用于 http 1.1.
如何保证系统实时更新
方法一:
以 vue 为例,vue 在打包的时候,css 和 js 名字都加了哈希值,所以改动后打包生成的 js 和 css 是唯一的,页面请求的是新资源,不会有缓存问题。但是入口文件 index.html 会因为缓存造成更新问题,如果我们更新了,但是浏览器使用的是缓存,就会出现问题。所以需要对入口文件设置不使用强制缓存,需要每次去服务器验证文件是否修改,即使用协商缓存。
server {
listen 80;
server_name 域名;
root 文件目录;
index index.html;
location {
try_files $uri /index.html;
}
location ~ .*\.(html)$ {
add_header Cache-Control no-store;
add_header Pragma no-cache
}
}
方法二:
-
最直接的办法
Internet 选项 -> Internet 临时文件“设置” -> “每次访问此页时检查”,缺点是要设置每台客户端,客户端较多时不可取
-
设置网页头(header)
状态码
- 200 from memory cache
- 状态码是灰色的,从内存中读取缓存的资源,强缓存。不请求服务器。
- 页面关闭会被内存释放,再次打开相同页面需要重新请求服务器,然后重新缓存在浏览器
- 脚本、字体、图片会被存放在内存中
- 200 from disk cache
- 状态码是灰色的,从磁盘中读取缓存的资源,强缓存,不请求服务器。
- 页面关闭不会被释放,这部分资源存在电脑磁盘中,只有用户手动清除浏览器缓存才会被释放。
- 较大的 css 文件、js 文件和 jpg 图片会存入硬盘
- 200
- 304
- 协商缓存。请求访问服务器,发现资源没有更新,使用本地资源。
磁盘和内存的区别
- 内存是计算机的工作场所,磁盘是用来存放暂时不用的信息
- 信息保存不同,内存中的信息会随刷新丢失,磁盘中的信息可以长久保存(除非手动删除)
- 磁盘的容量远大于内存
- cpu 只能读取内存里的数据,磁盘是作为存储空间的。
浏览器三级缓存原理
- 先查找内存,如果内存中存在,从内存中加载
- 如果内存中未找到,选择硬盘获取,如果硬盘中有,从硬盘中加载
- 如果硬盘中未找到,那就请求服务器,重新加载资源,加载到的资源缓存到硬盘和内存。