缓存

缓存

June 1, 2022
network

为什么需要缓存 #

  • 减少不必要的网络请求,提升页面访问速度
  • 减少服务器负载
  • 节省网络开销(流量)

缓存工作机制 #

通过 http 请求头及 http 响应头来控制

缓存类型 #

Private cache #

私有缓存:特定端的缓存,例如用户的浏览器

Shared cache #

源站和客户端之间的缓存,proxy cdn 等

Heuristic cache #

启发式缓存

http 的设计是能缓存尽量缓存,http 客户端根据 http 响应头自行决定缓存行为

缓存相关 header #

Cache-Control #

缓存控制响应头, HTTP/1.1 引入

  • max-age

    能存活多久(单位秒), 例: max-age=3153000

  • s-maxage

    跟 max-age 类似,作用于共享缓存,当这个存在时会忽略 max-age

  • private

    仅允许端(浏览器)缓存,私有缓存

  • public

    可被任意节点缓存

  • no-cache

    每次都需要验证缓存的有效性,强制校验,端仍可以缓存

    强刷时,浏览器请求头会带这个

  • no-store

    不允许被缓存,不推荐使用

  • immutable

    内容永远不会变,浏览器刷新时,不会去校验缓存有效性

HTTP/1.0 没法处理 no-cache 指令,用 max-age=0, must-revalidate 代替

推荐使用 no-cache,private

既可以当请求头(e.g. 浏览器 reload, force reload),也可以当响应头

Expires #

http 1.0 引入,不好 parse,不同端的实现有 bug,调整系统时钟会有 bug

Fri, 30 Oct 1998 14:19:41 GMT,优先级较低

服务端返回,GMT 时间戳。告诉浏览器在指定的时间戳之后重新获取新的资源。限制:服务器跟浏览器的时间必须保持同步

Last-Modified #

Mon, 03 Jan 2011 17:45:57 GMT

服务端返回 ,用来重新校验缓存是否有效, GMT 时间戳

不仅仅用于缓存,亦可用于在 cms 系统中表示上次修改时间,或告诉爬虫内容应被爬取的频率 等用途

因此 etag 和 last-modified 应都被使用

ETag #

e.g. ETag: x234dff

服务端返回 ,当浏览器端某个缓存过期,浏览器会发送一段 token(通常是文件的 hash 值)来请求服务器判断该文件是否过期。如果 ETag 不变,则继续使用缓存

比 last-modified 优先级更高

Vary #

根据不同的响应头缓存文件

e.g. Vary: Accept-Language

缓存校验 header #

过期的缓存不会立马被丢弃,端可通过跟源站沟通,判断缓存是否可以继续使用

If-Modified-Since #

Mon, 03 Jan 2011 17:45:57 GMT

浏览器端发送,在分布式系统中,时间同步,时间戳的解析比较复杂,容易出 bug,因此 etag/if-none-match 更常用

If-None-Match #

If-None-Match: x234dff

浏览器端发送 ,检查此值是否跟 server 端的 ETag 值匹配

强缓存与协商缓存 #

强缓存: 设置 expires 或者 cache-control 设置一个较长的 max-age, 浏览器在一段时间内直接用,不需要跟服务器通信

协商缓存: cache-control:no-cache 浏览器需要发请求给服务器,让服务器判断缓存是否有效