彻底理解浏览器的缓存机制
Web 缓存大致可以分为:数据库缓存、服务器端缓存(代理服务器缓存、CDN 缓存)、浏览器缓存。
浏览器缓存也包含很多内容: HTTP 缓存、indexDB、cookie、localstorage 等等。这里我们只讨论 HTTP 缓存相关内容。
在具体了解 HTTP 缓存之前先来明确几个术语:
- 缓存命中率:从缓存中得到数据的请求数与所有请求数的比率。理想状态是越高越好。
- 过期内容:超过设置的有效时间,被标记为“陈旧”的内容。通常过期内容不能用于回复客户端的请求,必须重新向源服务器请求新的内容或者验证缓存的内容是否仍然准备。
- 验证:验证缓存中的过期内容是否仍然有效,验证通过的话刷新过期时间。
- 失效:失效就是把内容从缓存中移除。当内容发生改变时就必须移除失效的内容。
浏览器缓存分类
浏览器缓存分为强缓存和协商缓存,浏览器加载一个页面的简单流程如下:
- 浏览器先根据这个资源的http头信息来判断是否命中强缓存。如果命中则直接加在缓存中的资源,并不会将请求发送到服务器。
- 如果未命中强缓存,则浏览器会将资源加载请求发送到服务器。服务器来判断浏览器本地缓存是否失效。若可以使用,则服务器并不会返回资源信息,浏览器继续从缓存加载资源。
- 如果未命中协商缓存,则服务器会将完整的资源返回给浏览器,浏览器加载新资源,并更新缓存。
缓存应用
常见的HTTP缓存只能存储GET响应,对于其他类型的响应则无能为力。普遍的缓存案例∶
●检索请求的成功响应∶响应状态码为200,则表示为成功。包含例如HTML文档,图片,或者文件的响应。
●不变的重定向∶响应状态码为301。●错误响应∶响应状态码为404的一个页面。
● 不完全的响应∶响应状态码为206,只返回局部的信息。
● 除了GET请求外,如果匹配到作为一个已被定义的cache键名的响应。
缓存控制
Cache-Control
Cache-Control是一个相对时间,例如Cache-Control:3600,代表着资源的有效期是3600秒。由于是相对时间,并且都是与客户端时间比较,所以服务器与客户端时间偏差也不会导致问题。
Cache-Control与Expires可以在服务端配置同时启用或者启用任意一个,同时启用的时候Cache-Control优先级高。
Cache-Control 可以由多个字段组合而成,主要有以下几个取值:
-
max-age 指定一个时间长度,在这个时间段内缓存是有效的,单位是s。例如设置 Cache-Control:max-age=31536000,也就是说缓存有效期为(31536000 / 24 / 60 * 60)天,第一次访问这个资源的时候,服务器端也返回了 Expires 字段,并且过期时间是一年后。
图下为 0 意为有效期为0
在没有禁用缓存并且没有超过有效时间的情况下,再次访问这个资源就命中了缓存,不会向服务器请求资源而是直接从浏览器缓存中取。
-
s-maxage 同 max-age,覆盖 max-age、Expires,但仅适用于共享缓存,在私有缓存中被忽略。
-
public 表明响应可以被任何对象(发送请求的客户端、代理服务器等等)缓存。
-
private 表明响应只能被单个用户(可能是操作系统用户、浏览器用户)缓存,是非共享的,不能被代理服务器缓存。
-
no-cache 强制所有缓存了该响应的用户,在使用已缓存的数据前,发送带验证器的请求到服务器。不是字面意思上的不缓存。
-
no-store 禁止缓存,每次请求都要向服务器重新获取数据。
-
must-revalidate**指定如果页面是过期的,则去服务器进行获取。这个指令并不常用,就不做过多的讨论了
用户行为与缓存
浏览器缓存行为还有用户的行为有关!!!
用户操作 | expires/cache-control | last-modified/etag |
---|---|---|
地址栏回车 | 有效 | 有效 |
页面链接跳转 | 有效 | 有效 |
新开窗口 | 有效 | 有效 |
前进,后退 | 有效 | 有效 |
F5刷新 | 无效 | 有效 |
Crtl+F5刷新 | 无效 | 无效 |