HTTP 强缓存和协商缓存
in HTTP with 0 comment

HTTP 强缓存和协商缓存

in HTTP with 0 comment

概述

良好的缓存策略可以降低资源的重复加载提高网页的整体加载速度
通常浏览器缓存策略分为两种:强缓存和协商缓存

基本原理

  1. 浏览器在加载资源时,根据请求头的 ExpiresCache-Control 判断是否命中强缓存,是则直接从缓存读取资源,不会发请求到服务器。
  2. 如果没有命中强缓存,浏览器会发送请求到服务器,通过 Last-ModifiedEtag 验证资源是否命中协商缓存,如果命中,服务器返回 304 Not Modified,但是不会返回这个资源的数据,浏览器会从缓存中读取资源。
  3. 如果前面两者都没有命中,直接从服务器加载资源。

强缓存

强缓存通过 ExpiresCache-Control 实现。

Expires

Expires 是 HTTP1.0 的实现,服务端返回 GMT 格式的时间,是资源的实效时间:

Expires: Wed, 11 May 2018 07:20:00 GMT

如果请求时间在此时间之前,则命中强缓存,使用本地资源。

缺点很明显,当服务器与客户端时间偏差较大时,会导致缓存混乱。

Cache-Control

Cache-Control 是 HTTP1.1 的实现,服务端会返回 max-age 相对时间:

Cache-Control: max-age=86400

max-age: 86400 表示该资源的过期时间为 86400s。

Cache-Control 优先级高于 Expires。也就是同时存在时浏览器会忽略 Expires

协商缓存

当强缓存未命中时,浏览器就会发一个请求到服务器,验证协商缓存是否命中,如果命中,服务器会返回 304 Not Modified 状态。

协商缓存利用的是 Last-Modified/If-Modified-SinceEtag/If-None-Match

Last-Modified

Last-Modified 是 HTTP1.0 的实现。浏览器第一次请求一个资源的时候,服务器返回的 header 中会加上 Last-ModifiedLast-Modified 是一个时间标识该资源的最后修改时间,例如 Last-Modified: Thu,31 Dec 2037 23:59:59 GMT

再次请求该资源时,请求头会加入 If-Modified-Since,服务器收到请求后会根据资源的最后修改时间判断是否命中缓存。

如果命中,则返回 304 Not Modified 不返回资源内容,不返回 Last-Modified

缺点:

Etag

Etag 是 HTTP1.1 的实现,是资源的唯一表示标识符,当文件内容不发生改变时,Etag 值不变。

请求相同资源时,浏览器会在请求头加入 If-None-Match 值是第一次请求该资源时的 Etag 值。服务器收到请求后判断是否命中缓存。

ETag 的优先级比 Last-Modified 更高。

协商缓存需要配合强缓存使用,如果不启用强缓存的话,协商缓存根本没有意义

其它

Cache-Control 的其它常见值

memory cache

memory cache 是内存中的缓存,(与之相对 disk cache 就是硬盘上的缓存)。按照操作系统的常理:先读内存,再读硬盘。disk cache 将在后面介绍 (因为它的优先级更低一些),这里先讨论 memory cache。

几乎所有的网络请求资源都会被浏览器自动加入到 memory cache 中。但是也正因为数量很大但是浏览器占用的内存不能无限扩大这样两个因素,memory cache 注定只能是个“短期存储”。常规情况下,浏览器的 TAB 关闭后该次浏览的 memory cache 便告失效 (为了给其他 TAB 腾出位置)。而如果极端情况下 (例如一个页面的缓存就占用了超级多的内存),那可能在 TAB 没关闭之前,排在前面的缓存就已经失效了。

memory cache 机制保证了一个页面中如果有两个相同的请求 (例如两个 src 相同的 <img>,两个 href 相同的 <link>)都实际只会被请求最多一次,避免浪费。

disk cache

disk cache 也叫 HTTP cache,顾名思义是存储在硬盘上的缓存,因此它是持久存储的,是实际存在于文件系统中的。而且它允许相同的资源在跨会话,甚至跨站点的情况下使用,例如两个站点都使用了同一张图片。
disk cache 会严格根据 HTTP 头信息中的各类字段来判定哪些资源可以缓存,哪些资源不可以缓存;哪些资源是仍然可用的,哪些资源是过时需要重新请求的。当命中缓存之后,浏览器会从硬盘中读取资源,虽然比起从内存中读取慢了一些,但比起网络请求还是快了不少的。绝大部分的缓存都来自 disk cache。

面试题:请求时浏览器缓存 from memory cachefrom disk cache 的依据是什么,哪些数据什么时候存放在 Memory Cache 和 Disk Cache 中?

依据: 请求资源命中强缓存。

何时从 memory 取缓存? 何时从 disk 取缓存? 我没能在网上找到标准的答案,以下是个人理解:

参考文章