写在前面,知识点整理参考了MDN与其他博客的观点,然后加上了自己的理解,如有侵权,与我联系.
前言:
web的性能优化是离不开HTTP缓存的,重用已获取的资源可以有效的提高网站应用的性能.缓存可以减少请求次数和复用资源,从而减轻网络延迟和阻塞等情况,进而提升用户体验.
知识点导读
- 缓存的基本介绍
- 缓存的工作机制
- 缓存的相关首部介绍
缓存的基本介绍
缓存的基本定义
缓存指的是保存请求资源副本,方便后续请求时直接使用副本,而不需要重新请求资源.
缓存策略的作用和关键点
- 作用:缓存复用资源可以有效减缓服务器压力,提升性能,提升用户体验,是web性能优化的重要组成部分.
- 关键点: 资源往往不是一成不变的,所以策略中重要一点在于感知服务器资源的更改,即时更新缓存,避免使用已过期缓存
缓存的分类
缓存分类大致分为两类, 私有(浏览器)缓存(private cache) 和 共享缓存(shared cache),当然其他还有CDN缓存等等.
- 私有缓存(浏览器缓存) 浏览器缓存针对的是单独的用户,指的是就是浏览器的缓存机制,缓存文档,图片,js文件等静态资源,浏览器的前后导航,源码浏览等功能就是基于浏览器缓存,也是我们主要学习的对象.
- 共享缓存(代理缓存) 代理缓存提供给多个用户,需要代理服务器的支持,减少主要服务器的压力,减少网络拥堵.
缓存的目标(用处)
- 成功响应 常见的资源请求的成功响应(get方法,响应值为200 ok),包括HTML文档,图片,视频以及JS,CSS等文件
- 永久重定向 请求响应状态码为301(服务器资源被移动)
- 资源不存在 请求响应状态码为404
- 不完全响应 请求状态码为 206 ,请求内容的部分,用作断点续传和大文件分批下载
缓存的工作机制
照理来说,浏览器的缓存副本应该一直被保存使用,但是有两个原因不允许这么做.
- 浏览器为每一个web应用设定了有限的缓存空间,所以浏览器会定期删除一些缓存副本,这个过程称为缓存驱逐.
- 服务器的资源可能会存在变化,此时浏览器中的缓存也需要替换更新.
新鲜度
接下来理解一个概念--新鲜度
浏览器与服务器之间会约定一个过期时间,过期时间之前,缓存是新鲜的,过期时间之后,缓存将变为陈旧的.
- 新鲜的缓存在资源请求时会直接被使用,而不用与服务器通信,这阶段被称为强缓存
- 陈旧的缓存在资源请求时,无法判断缓存是否继续有效,需要与服务器通信从而确定是选择新内容还是继续使用原先的缓存,这阶段被称为协商缓存
强缓存
强缓存的依据是过期时间,而过期时间则依靠响应首部信息,以下首部信息优先级按序号排列
- Cache-control:max-age = N , 此处的N就代表缓存寿命,用以判断缓存过期与否
- 不存在Cache-control的情况下, 使用Expires 与 Date(再次请求)两者判断缓存是否过期
- 两者都不存在时,使用Last-modified 和 Date(缓存副本的请求)两者判断缓存是否过期,(缓存寿命为 (Date - Last-modified )/ 10)
协商缓存
- 如果请求时计算出缓存为陈旧的,就会进行协商缓存,也就是缓存验证.
- 请求首部会带上文件特征标识(If-None-Match 或 If-Modified-Since),服务器获取请求首部的文件特征标识从而判断浏览器的缓存是否有效.
- 如果缓存文件继续有效就返回状态码304(not modified)且不含实体信息,表明浏览器缓存是新鲜的可以继续使用,
反之返回状态码200和实体信息表示浏览器缓存已失效,浏览器使用缓存驱逐把就旧缓存替代为新缓存.
协商缓存的两种方式
- Etag 和 If-None-Match
Etag可以看做是服务器文件的唯一标识,http响应时携带该首部,后续请求时该Etag会被记录为请求首部的If-None-Match,服务器通过比较文件现在的Etag和首部的If-None-Match从而进行缓存验证. - Last-Modified 和 If-Modified-Since
Last-Modified 代表文件上次修改时间,http响应时携带该首部,后续请求时请求首部If-Modified-Since 携带这个信息,服务器比较该首部和文件当前修改进行缓存验证.
Last-Modified 和 If-Modified-Since可以作为一种弱校验器,说它弱是因为它只能精确到一秒。
缓存的相关首部介绍
-
Cache-control 用已描述资源的缓存规则,
- Cache-Control: no-store 禁止缓存,每次请求返回实体内容
- Cache-Control: no-cache 强制缓存验证
- Cache-Control: private 缓存只用于用户
- Cache-Control: public 缓存可用于中间代理
- Cache-Control: max-age= seconds 缓存的寿命,判断缓存的新鲜度,也是强缓存和协商缓存的判断依据之一
-
Expires 缓存的过期时间
-
Etag 响应返回的文件标识
-
If-None-Match 协商缓存时值为Etag的文件标识,用于缓存验证
-
Last-Modified 响应返回的文件修改时间
-
If-Modified-Since 协商缓存时值为Last-Modified的文件修改时间,用于缓存验证