强制缓存:根据Expires(response header里的过期时间)判断,浏览器再次加载资源时,如果在这个过期时间内,则命中强缓存,并不会向服务端发起请求,展示为200状态。
协商缓存:客户端向服务端发送带有If-None-Match和If-Modified-Since的请求进行协商判断,如果资源没有变化继续使用本地缓存,记录为304状态;如果资源发生变化,服务端响应数据,记录为200状态。
Expires-响应头。(强制缓存,200状态)
服务器和浏览器约定资源过期时间。在过期时间之前,浏览器不会发起服务器请求,读取的都是缓存资源;过期以后,浏览器重新请求服务器资源,服务器返回资源的同时,告诉浏览器一个新的过期时间。
优势:
- 在过期时间以内,为用户省了很多流量。
- 减少了服务器重复读取磁盘文件的压力。
缺点:
- expires不稳定,浏览器可以随意更改客户端时间
- 缓存时间过期以后,服务器不管文件有没有变化,都会重新返给浏览器。
Last-Modified-响应头
资源最近修改时间,由服务器告诉浏览器。为了改善expires的缓存缺点,服务器在第一次返回请求资源的同时,告诉浏览器文件最后的更新时间Last-Modified。
当expires过期时间到达以后,浏览器带上 If-Modified-Since(等于上一次请求的Last-Modified) 请求服务器。
服务器判断请求头的时间,与文件最后一次修改的时间做对比。
如果相等,则告诉浏览器你可以继续用本地缓存(304)
如果不相等:服务器返回最新资源,同时告诉浏览器文件的最近的修改时间 Last-Modified 以及过期时间 Expires
缺点:
- Last-Modified 过期时间只能精确到秒。如果一个文件在1秒内变动多次,浏览器发起的请求,就有可能拿不到最新的文件内容。
Etag响应头
资源标识,由服务器告诉浏览器。为了解决Last-Modified 过期时间只能精确到秒的问题,引入Etag,文件内容不变,Etag就不变。同时引入请求头If-None-Match就是服务器返回的Etag。
当服务器收到浏览器的If-Modified-Since和If-None-Match,则比较If-None-Match和文件的Etag值进行比较,忽略If-Modified-Since的比较。
如果Etag和If-None-Match一致,服务器告诉浏览器继续使用本地缓存(304)。
Cache-Contorl请求/响应头
缓存控制字段,精确控制缓存策略。cache-control增加了相对时间的控制,比如:max-age=60(强缓存)
意思是在60秒以内,使用缓存到浏览器的资源。
Cache-Control 除了可以设置 max-age 相对过期时间以外
-
public,资源允许被中间服务器缓存。 浏览器请求服务器时,如果缓存时间没到,中间服务器直接返回给浏览器内容,而不必请求源服务器。
-
private,资源不允许被中间代理服务器缓存。浏览器请求服务器时,中间服务器都要把浏览器的请求透传给服务器。
-
no-cache,浏览器不做缓存检查。每次访问资源,浏览器都要向服务器询问,如果文件没变化,服务器只告诉浏览器继续使用缓存(304)。
-
no-store,浏览器和中间代理服务器都不能缓存资源。每次访问资源,浏览器都必须请求服务器,并且,服务器不去检查文件是否变化,而是直接返回完整的资源。
缓存存储位置
内存缓存(memory cache)和硬盘缓存(disk cache)
| 区别 | 内存缓存 | 硬盘缓存 |
|---|---|---|
| 存储内容 | JS,字体,图片等 | CSS等 |
| 读取速度 | 快 | 慢 |
| 时效性 | 进程关闭则清空 | 可以缓存较长时间 |
| 空间 | 空间小 | 空间大 |
总结:在前端项目中使用缓存策略的过程中,html文件不建议采用缓存,每次访问都应该请求服务器,毕竟用户肯定想看到最新的内容,像js、css文件地址加上hash策略,并到缓存里面,可以大大的减少减少服务器压力。