简易笔记:浏览器缓存策略

HTTP头信息

首先咱们从资源被请求时,请求行为和资源缓存的不一样来看下HTTP头信息的表现:html

资源的首次请求: node

页面刷新-资源缓存未过时: web

页面刷新-资源缓存已过时-资源未变动: npm

页面刷新-资源缓存已过时-资源已变动: json

资源被再次请求时-缓存未过时: segmentfault

缓存策略

当浏览器请求资源文件时,默认会将源资文件缓存到本地以便重复使用,加快网页的加载速度。浏览器

浏览器的资源缓存分为 from disk cachefrom memory cache 两类。当首次访问网页时,资源文件被缓存在内存中,同时也会在本地磁盘中保留一份副本。当用户刷新页面,若是缓存的资源没有过时,那么直接从内存中读取并加载。当用户关闭页面后,当前页面缓存在内存中的资源被清空。当用户再一次访问页面时,若是资源文件的缓存没有过时,那么将从本地磁盘进行加载并再次缓存到内存之中。缓存

服务器能够经过Response Headers使用 expirescache-control 设置一个有效的过时时间,当浏览器再次请求资源时会判断本地缓存是否已过时:性能优化

  1. 若是没有过时那么直接从本地缓存读取,不会产生http请求,此为 强缓存
  2. 若是已过时,那么浏览器将从新向服务器请求资源,这一过程每每伴随着 缓存检测

expires

这是HTTP1.0版本的产物,属于 Response Headers,使用一个UTC格式的日期时间字符串表示资源的过时时间。服务器

使用 expires 设置的过时时间是以服务器时间为准的,它可能跟浏览器时间不一致,不一样时区也会存在影响。

cache-control

这是HTTP1.1版本的产物,属于 Response Headers,提供更多详细的缓存策略,能够根据三种不一样性质经过逗号进行组合使用:

  1. 是否不使用缓存: cache-control: no-store/no-cache/must-revalidate
  2. 是否为私有缓存: cache-control:public/private
  3. 设置过时时间: cache-control: max-age/s-maxage

是否不使用缓存:

  1. must-revalidate : 当本地的资源缓存没有过时前,使用本地缓存;当本地资源缓存已过时时,须要进行缓存检测(默认值)。
  2. no-cache : 无论本地的资源缓存是否过时,都须要进行缓存检测。
  3. no-store : 禁止浏览器缓存资源,每次请求资源都去服务器从新下载。

是否为私有缓存:

  1. public : 公共缓存,表示浏览器和代理服务器均可以设置缓存(默认值)。
  2. private : 私有缓存,仅浏览器设置缓存。

设置过时时间:

  1. max-age:使用 cache-control: max-age=60 的形式表示本地缓存的资源将在xx秒以后过时,单位为秒,会覆盖 Expires 的设置。
  2. s-maxage : 使用方式同 max-age ,在public设置下有效,针对共享缓存(代理服务器)有效。

使用 max-age 的优势在于设置的过时时间是一个相对于浏览器的时间,不受服务器和浏览器时间不一致的影响,也不会由于时区的不一样而受到影响。

启发式缓存

当资源文件的 Response Headers 中带有 last-modified 字段,可是却缺乏 expirescache-control 用来表示资源缓存的过时时间的字段,这个时候浏览器会使用启发式缓存来确认该资源缓存的过时时间:

浏览器会根据 datelast-modified 之间的时间差值的10%来做为资源缓存的过时时间。

缓存检测

当浏览器从新向服务器请求资源时,若是原先的 Response Headers 中存在 last-modified 或者 etag 信息,那么在 Request Headers 中会经过 if-modified-sinceif-none-match 将以前的信息带给服务器进行检测。若是服务器资源相对于本地的资源缓存没有发生变动,那么将会返回304状态码,表示资源未更新,让浏览器使用本地的资源缓存,这就是 协商缓存

若是原先的 Response Headers 中没有 last-modifiedetag 信息,那么将从服务器从新下载资源文件。

last-modified 和 if-modified-since

这两个字段都是HTTP1.0版本的产物。

  1. last-modified: 属于 Response Headers,表示资源最后一次修改的时间。

  2. if-modified-since: 属于 Request Headers,用来判断服务器端资源是否在该传递的时间以后作了修改,若是没有修改那么服务器将返回304状态码,让浏览器使用资源缓存。

etag 和 if-none-match

这是HTTP1.1版本的产物。

  1. etag: 属于 Response Headers,表示资源的惟一标识符,由服务器端生成。

  2. if-none-match: 属于 Request Headers,用来判断服务器资源是否与该传递的标识符不一致,若是一致则表示资源文件没有修改过,服务器将返回304状态码,让浏览器使用资源缓存。会覆盖 if-modified-since 的设置。

使用etag来判断服务器端资源文件是否作了修改,主要有如下考虑:

  1. last-modified 只能精确到秒,而有些服务器资源可能在1秒内进行了屡次修改。
  2. 服务器资源文件,有些会定时自动生成,可是文件内容并无发生任何变动。

用户行为

浏览器的缓存策略还跟用户的行为有关:

  1. 当用户从url地址栏回车访问网页时,强缓存和协商缓存都有效。
  2. 当用户从页面中点击一个超连接访问网页时,强缓存和协商缓存都有效。
  3. 当用户按F5刷新时,强缓存将无效,但会触发协商缓存。不过在Firefox浏览器中,强缓存和协商缓存均无效。
  4. 当用户按Ctrl+F5强制刷新时,强缓存和协商缓存都将无效,浏览器将向服务器从新并下载资源文件。

demo检验

为了完全搞清楚浏览器的缓存策略,这里提供了一个使用node http模块构建的一个简单服务器环境,经过自行设置Response Headers来预览浏览器缓存的表现行为。点击下载资源包

下载资源包后,自行解压,而后使用 npm install 命令安装依赖,经过 node server 执行目录下的server.js文件来启动本地服务器,将会自动使用默认浏览器打开目录下的 /pages/index/index.html 页面。

以后能够在cache.json配置文件的下图所示的代码中,对浏览器缓存涉及到的四个http字段进行编辑,修改完毕后保存并强制刷新浏览器页面便可:

编辑说明:

  1. 设置相关字段为false,则表示不设置相应的http字段;
  2. 对于Cache-Control字段的值,填写其支持的策略组合便可;
  3. 对于Expires字段的值,按秒填写数字便可;
  4. 对于Etag和Last-modified字段的值,设置为true便可;

参考资源

  1. 完全理解浏览器缓存机制
  2. 透过浏览器看HTTP缓存
  3. 浏览器缓存机制剖析
  4. 完全弄懂 Http 缓存机制 - 基于缓存策略三要素分解法
  5. web性能优化之:no-cache与must-revalidate深刻探究
  6. 由memoryCache和diskCache产生的浏览器缓存机制的思考
相关文章
相关标签/搜索