浏览器缓存解析——浅谈http缓存之强缓存协商缓存
2023-11-28 10:48:39
缓存机制在软件领域广泛存在,作为一种优化手段,对于提升用户的体验和降低服务器的负载有着重要意义。
01 浏览器缓存概述
HTTP 缓存就是利用 HTTP 请求头中的 Cache-Control 和 Expires 字段对资源的有效期进行控制,当浏览器再次请求该资源时,会先判断该资源是否过期,若未过期,则直接从缓存中加载,这样可以减少不必要的网络请求,提升网页的加载性能。
HTTP 缓存分为强缓存和协商缓存,强缓存优先级高于协商缓存,在命中强缓存失败的情况下,才会走协商缓存。
02 强缓存
强缓存通过 Expires 和 Cache-Control 控制,Cache-Control 是 HTTP 1.1 中新引入的字段,它比 Expires 更为强大和灵活,可以更精确地控制缓存的行为。
Expires
Expires 是一个相对时间,表示资源的绝对过期时间,当资源的请求时间超过 Expires 指定的时间时,浏览器将不会再从缓存中加载该资源,而是向服务器发出新的请求。
Cache-Control
Cache-Control 是一个指令性的字段,它可以指定资源的缓存行为,常用的指令有:
max-age=<seconds>
:表示资源的最大生存时间,单位为秒,在 max-age 指定的时间内,浏览器将直接从缓存中加载资源,而不会向服务器发出新的请求。public/private
:表示资源是否可以被公共缓存(如 CDN)缓存,public 表示可以被公共缓存缓存,private 表示只能被私有缓存(如浏览器缓存)缓存。no-cache/no-store
:表示资源不能被缓存,no-cache 表示浏览器在每次请求资源时都会向服务器发出新的请求,而不会从缓存中加载资源,no-store 表示浏览器不能存储资源的任何副本。
03 协商缓存
协商缓存通过 Last-Modified 和 Etag 控制,当资源的请求时间超过 Expires 指定的时间或 Cache-Control 指令允许的情况下,浏览器将向服务器发出一个条件请求,询问资源是否发生变化。
Last-Modified
Last-Modified 表示资源的最后修改时间,服务器在响应请求时会将 Last-Modified 字段的值设置为资源的最后修改时间。浏览器在下次请求该资源时,会在请求头中带上 If-Modified-Since 字段,并将 If-Modified-Since 字段的值设置为 Last-Modified 的值。如果服务器发现资源的最后修改时间没有发生变化,则会返回一个 304 Not Modified 状态码,表示资源没有发生变化,浏览器将直接从缓存中加载资源。
Etag
Etag 是一个唯一标识符,表示资源的当前状态,服务器在响应请求时会将 Etag 字段的值设置为资源的 Etag。浏览器在下次请求该资源时,会在请求头中带上 If-None-Match 字段,并将 If-None-Match 字段的值设置为 Etag 的值。如果服务器发现资源的 Etag 没有发生变化,则会返回一个 304 Not Modified 状态码,表示资源没有发生变化,浏览器将直接从缓存中加载资源。
04 提高http缓存命中率
为了提高http缓存命中率,减少不必要的请求,进一步提升网页的加载性能,可以采取以下措施:
- 设置合理的 Expires 和 Cache-Control 头,确保资源的有效期足够长,但又不会过长。
- 使用强缓存,而不是协商缓存,因为强缓存的优先级更高,命中率也更高。
- 使用 Etag 代替 Last-Modified,因为 Etag 可以更精确地标识资源的变化。
- 使用 CDN 来缓存资源,CDN 可以将资源缓存到离用户更近的位置,从而减少资源的加载时间。