发起一个 HTTP 请求的流程

HTTP 缓存

强缓存

向浏览器缓存查找该请求结果,并根据该结果的缓存规则来决定是否使用该缓存结果的过程

强制缓存的情况:

  1. 如果不存在该缓存结果和缓存标识,则缓存失效。直接向服务器发起请求

  2. 存在该缓存结果和表示,但已失效,则使用协商缓存

  3. 存在该缓存结果和表示,且尚未失效,直接返回缓存结果

控制强缓存的字段有:

  1. Expires

Expres 是HTTP/1.0网页缓存的字段
Expires 存储的是一个缓存过期时间,如果缓存过期,则直接向服务器发起请求

  1. Cache-Control

Cache-Control 比 Expires 优先级更高,若两个字段同时存在,则取 Cache-Control 的缓存规则

Expires 是使用服务器时间与客户端时间作对比,如果两边有一方时间不准确,或者时区不一样,则缓存就不会有效。

Cache-Control 取值:

  • public 所有内容都将被缓存(客户端和代理服务器都可以缓存)

  • private 所有内容只有客户端可以缓存 (默认取值)

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

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

  • max-age=x 缓存内容将在 x 秒后失效

浏览器缓存存放位置和顺序

  • from disk cache 存放在硬盘中;读取需要进行 I/O 操作

  • from memory cache 存放在内存中;速度快,时间限制

读取顺序: memory -> disk -> 服务器请求

浏览器会在 js 和图片等文件解析后存入内存缓存中,等页面刷新是从内存中取出。
而 css 则会存放在硬盘中,每次渲染会从硬盘中读取

协商缓存

协商缓存就是强制缓存失效后,浏览器携带缓存标识向服务器发起请求,由服务器根据缓存标识决定是否使用缓存的过程,主要有以下两种情况:

  1. 协商缓存生效,返回 304

  2. 协商缓存失效,返回 200

协商缓存字段

  • Last-Modifyed 服务器返回资源时,该资源的最后修改时间

  • If-Modifyed-Since 当再次请求时,带上资源上次请求返回的最后修改时间,然后与 Last-Modifyed 作对比,如果相同,代表资源未更新,可以继续使用缓存,返回 304,如果不同,则重新返回资源,返回 200。

  • Etag 当前资源的唯一表示(由服务器生成)

  • If-None-Match 当再次请求时,带上上一次请求的 Etag,服务器收到后,与当前资源的 Etag 作对比,如果相同,代表资源未更新,继续使用缓存,返回 304。如果不同,则重新返回资源,返回 200。

Etag / If-None-Match 优先级比较高

协商缓存使用 Ctrl+F5 刷新可以使缓存无效。强缓存则不行,需要更改资源的路径才能使缓存失效。

强缓存优先于协商缓存

浏览器缓存

本地小容量存储

  • Cookie

  • LocalStorage 长期缓存,数据一致保存在浏览器内,知道被用户手动清除为止

  • SessionStorage 属性与 LocalStorage 差不多。但是 SessionStorage 在页面关闭后会清除

本地大容量存储

  • WebSql 浏览器的关系型数据库,大小 50MB,现在已被 W3C 标准废弃

  • IndexDB 浏览器的非关系型数据库,大小 50MB

往返缓存(BFCache)

浏览器在前进后退按钮上为了提升历史页面的渲染速度的一种策略。
当用户前往新页面时,将当前页面的浏览器 DOM 状态保存到 bfcache 中;
当用户点击后退按钮的时候,将页面直接从 bfcache 中加载,节省了网络请求的时间

离线缓存 Manifest

利用离线缓存,在用户没有连接网络时,也能正常访问网页。

原理

HTML5 的离线存储是基于一个新建的 .appcache 文件的缓存机制(不是存储技术),通过这个文件上的解析清单离线存储资源,这些资源就会像 cookie 一样被存储了下来。之后当网络在处于离线状态下时,浏览器会通过被离线存储的数据进行页面展示

使用

创建一个和 html 同名的 manifest 文件,然后在页面头部加入 manifest 属性

<html manifest="test.manifest"></html>

manifest 语法

  • CACHE: 表示需要离线存储的资源列表,由于包含 manifest 文件的页面将被自动离线存储,所以不需要把页面自身也列出来。

  • NETWORK: 表示在它下面列出来的资源只有在在线的情况下才能访问,他们不会被离线存储,所以在离线情况下无法使用这些资源。不过,如果在 CACHE 和 NETWORK 中有一个相同的资源,那么这个资源还是会被离线存储,也就是说 CACHE 的优先级更高。

  • FALLBACK: 表示如果访问第一个资源失败,那么就使用第二个资源来替换他,比如上面这个文件表示的就是如果访问根目录下任何一个资源失败了,那么就去访问 offline.html 。

CACHE MANIFEST
    #v0.11
    CACHE:
    js/app.js
    css/style.css
    NETWORK:
    resourse/logo.png
    FALLBACK:
    / /offline.html

更新离线缓存

  • 更新 manifest 文件
  • 清除浏览器缓存
  • 通过 javascript 操作

注意

  1. 浏览器对缓存数据的容量限制可能不太一样(某些浏览器设置的限制是每个站点 5MB)。
  2. 如果 manifest 文件,或者内部列举的某一个文件不能正常下载,整个更新过程都将失败,浏览器继续全部使用老的缓存。
  3. 引用 manifest 的 html 必须与 manifest 文件同源,在同一个域下。
  4. FALLBACK 中的资源必须和 manifest 文件同源。
  5. 当一个资源被缓存后,该浏览器直接请求这个绝对路径也会访问缓存中的资源。
  6. 站点中的其他页面即使没有设置 manifest 属性,请求的资源如果在缓存中也从缓存中访问。
  7. 当 manifest 文件发生改变时,资源请求本身也会触发更新。