浏览器缓存策略|8月更文挑战

342 阅读4分钟

浏览器缓存策略

  • 浏览器的缓存分为强缓存协商缓存,他们都是通过http报文的缓存标识进行的

强缓存

  • 强缓存的缓存标识有ExpiresCache-Control
  • Expires 是http/1.0中控制资源的过期时间,如果客户端的时间小于Expires,那么直接使用缓存,到了http1.1Expires已经被Cache-Control这个字段替代。Cache-Control是精准控制缓存的字段。他里面的有如下取值
  • public:所有内容都将被缓存(客户端和代理服务器都可缓存)

private:所有内容只有客户端可以缓存,Cache-Control的默认取值

no-cache:客户端缓存内容,但是是否使用缓存则需要经过协商缓存来验证决定

no-store:所有内容都不会被缓存,即不使用强制缓存,也不使用协商缓存

max-age=xxx (xxx is numeric):缓存内容将在xxx秒后失效

协商缓存(弱缓存)

  • 如果缓存标识没有命中强缓存,那么就会走协商缓存。协商缓存也是由缓存标识来决定如果缓存的
  • Etag/ If-None-MatchEtag服务器请求响应时,返回的当前资源的唯一标识。等客户端发送请求时,If-None-Match会携带上上次返回的Etag,服务器会将If-None-Match的字段跟该资源在服务器的Etag做对比,如果一致,说明资源没有更新,返回304.如果不一致,则重新返回资源文件,状态码是200
  • Last-Modified/ If-Modified-Since: Last-Modified服务器返回资源最近修改的时间。由服务器返回给客户端。Last-Modified-Since是·客户端最近修改资源的时间·。由客户端告诉服务器。当客户端请求服务器时,会将二者时间进行比对,如果服务器的资源最后被修改时间大于If-Modified-Since的字段值 则重新返回资源文件,状态码是200。否则说明资源没有更新,返回304.

为什么有了强缓存,还需要协商缓存

1. 解决强缓存的局限性

  • 问题:强缓存过期前,浏览器无法感知资源是否已更新。

  • 例子

    • 某 CSS 文件设置 max-age=86400(1 天),但开发者 1 小时内修复了 Bug。
    • 用户在此期间访问,会一直使用错误的缓存版本。

2. 协作流程

  1. 强缓存优先:在有效期内直接使用缓存(最快)。

  2. 强缓存失效后:启用协商缓存,向服务器验证资源是否变化(平衡速度和 freshness)。

    • 若未变化 → 继续用缓存(304)。
    • 若变化 → 获取新资源(200)。

总结

  • 浏览器的缓存机制,是强缓存优先于弱缓存
  • 强缓存里Cache-Control优先于Expires,甚至有的网页都不返回Expires。Cache-Control的取值,对得起这个精准缓存,只传一个取值,是就是,不是就是不是
  • 强缓存没有命中会走协商缓存,协商缓存也是通过缓存标识来决定的。
  • Etag/ If-None-Match 优先级高于Last-Modified/ If-Modified-Since,前者是唯一标识比对,后者是时间比对。说明还是唯一标识靠谱,这个时间比对,像是强缓存Expires的一个升级版
  • 上一条说了比对,那比对就是客户端和服务端做比对,所以协商缓存是走网络的。但是强缓存是通过Cache-Control来进行缓存标识,是不走网络滴,只看有没有对应的字段即可
  • 304解释:服务端已经执行了GET,但文件未变化,返回304

缓存相关的header

  • Expires: 资源的过期时间

  • Cache-Control: 缓存控制字段,精确控制缓存字段

  • if-Modified-Since: 请求头,资源最近修改时间,由浏览器告诉服务器

  • Last-Modified: 响应头 资源最近修改时间,由服务器告诉浏览器

  • if-None-Match: 请求头,缓存资源标识,由浏览器告诉服务器

  • Etag: 响应头,缓存资源标识 ,由服务器告诉浏览器