背景
浏览器缓存是Web应用性能优化的一个重要环节,使用缓存可以减少浏览器向服务器请求资源的次数,从而加快客户端加载网页的速度,减小服务器压力
浏览器缓存分类
浏览器缓存策略主要有两种:强缓存和协商缓存。
浏览器在给服务器发送第一次请求后,再发送后续请求时,会先读取上一次返回header中的信息
- 强缓存:返回的header中的expires、cache-control字段命中强缓存,则下一次发请求时直接从缓存中返回,不与服务器通信
- 协商缓存:如果header中没有命中强缓存的信息,浏览器发送携带header信息的请求到服务端,由服务端判断是否命中协商缓存,如果命中则服务器返回新的响应header信息更新缓存中的对应header信息,但是并不返回资源内容,它会告知浏览器可以直接从缓存获取;否则返回最新的资源内容
强缓存是在本地判断缓存是否过期,没有与服务端交互,获得到的缓存也是本地的内容。
协商缓存是通过发送本地缓存的header信息到服务端,由服务端判断header信息中缓存是否过期,如果没过期客户端仍然使用本地缓存,如果过期服务端返回新的资源。
强缓存
强缓存通过header头部信息中的expires和cache-control字段判断是否过期。
- expires字段表示缓存过期时间,是服务端返回的绝对时间,GTM格式(我们用的GTM+8,隔8个小时),会存在服务器与客户端时间偏差导致缓存混乱的问题。逐渐被 cache-control替代
- cache-control字段通过max-age来设置缓存持续时间
以下是几个cache-control相关字段及其含义
字段 | 含义 |
---|---|
no-cache | 告知浏览器不直接使用本地缓存,要先向服务器发起请求 |
no-store | 禁止浏览器缓存资源,每次都要向服务器请求资源,每次请求都会下载完整的资源 |
max-age | 缓存资源的有效时间,从浏览器第一次发请求的时间算起 |
public | 可以被所有用户缓存,包括浏览器或代理 |
private | 仅允许客户端浏览器缓存,不允许CDN等中间代理缓存 |
协商缓存
服务端判断请求是否命中协商缓存的时候,需要使用到 Last-Modified 或者 Etag 字段,Last-Modified基于修改时间,Etag基于文件内容
浏览器第一次请求一个资源的时候,服务器返回的header中会加上Last-Modify,标识该资源的最后修改GTM绝对时间,例如 Last-Modify: Thu,31 Dec 2037 23:59:59 GMT。
当浏览器再次请求该资源时,request的请求头中会包含If-Modify-Since,该值为缓存之前返回的Last-Modify。服务器收到If-Modify-Since后,根据资源的最后修改时间判断是否命中缓存。
如果命中缓存,则返回304 Not Modified,并且不会返回资源内容,并且不会返回Last-Modify。
Etag/If-None-Match返回一个校验码。ETag可以保证每一个资源是唯一的,资源变化都会导致ETag变化。服务器根据浏览器上送的If-None-Match值来判断是否命中缓存。
与Last-Modified不一样的是,当服务器返回304 Not Modified的响应时,由于ETag重新生成过,response header中还会把这个ETag返回,即使这个ETag跟之前的没有变化。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。