浏览器的缓存过程

193 阅读7分钟

浏览器缓存是指在浏览网页时,浏览器会将某些资源(如 HTML、CSS、JavaScript 文件、图像等)存储在本地,以便在下一次访问相同的资源时,可以从本地读取,而不需要再次从服务器请求。这样可以减少网络请求的数量,提高网页加载速度和用户体验。 下面是浏览器缓存的主要过程以及相关技术的解释:

1. 浏览器缓存的基本流程

浏览器缓存主要分为两个阶段:

  • 初次请求:当用户第一次访问某个页面时,浏览器会发送请求到服务器,服务器响应资源,同时附带缓存控制策略(如 HTTP 响应头),浏览器根据这些策略决定如何存储这些资源。
  • 后续请求:当用户再次访问该页面时,浏览器会检查本地缓存是否有这些资源,并根据缓存策略判断是使用缓存中的资源,还是重新向服务器请求更新的资源。

2. 缓存的类型

浏览器缓存涉及多种类型的缓存,主要包括:

  • 内存缓存(Memory Cache) :一些短期使用的资源会暂时保存在内存中,当用户关闭页面或标签时,这些资源就会被清除。内存缓存的响应速度最快,但存储时间较短。
  • 硬盘缓存(Disk Cache) :资源保存在硬盘上,生命周期较长。下次用户重新打开浏览器或访问相同页面时,硬盘缓存中的资源可以被重新加载。硬盘缓存比内存缓存速度稍慢,但可以存储更大、更持久的内容。
  • 服务端缓存(Server-side Cache) :服务端可能会使用反向代理、CDN 等技术来缓存静态资源,从而减少服务器负载和加快响应速度。
  • 浏览器存储(LocalStorage、SessionStorage、IndexedDB) :除了传统的缓存机制,现代浏览器还提供了其他持久化存储选项,比如 LocalStorage 和 IndexedDB,它们可以用于存储用户数据或应用状态。

3. 缓存的控制与策略

浏览器缓存的控制依赖于 HTTP 头信息,以下是几个重要的 HTTP 头,用来指定浏览器缓存资源的行为:

1. Cache-Control

Cache-Control 是一个 HTTP 响应头,用来指示浏览器和中间缓存服务器如何缓存和使用资源。

  • max-age:指定资源的有效期,单位为秒。在指定时间内,浏览器会使用缓存中的资源,而不请求服务器。例如,Cache-Control: max-age=3600 表示资源可以在 3600 秒内不请求服务器。
  • no-cache:告诉浏览器资源可以被缓存,但是每次使用缓存前需要向服务器发送请求验证资源是否已经更新。它并不禁止缓存,而是要求强制验证。
  • no-store:完全禁用缓存,每次请求都会向服务器重新获取资源,不会将任何资源缓存下来。
  • private:表示资源只能被浏览器缓存,不能被中间代理服务器缓存。
  • public:表示资源可以被浏览器和任何中间缓存代理服务器缓存。

2. ETag

ETag 是一个 HTTP 响应头,代表资源的特定版本。它的作用是提供资源的唯一标识符,服务器可以通过 ETag 来判断缓存的资源是否与服务器上的资源一致。

  • 首次请求:服务器生成一个唯一的 ETag 并返回给浏览器。
  • 后续请求:浏览器在发送请求时附带 If-None-Match: <ETag>,服务器比较资源的 ETag,如果资源没有改变,返回 304 Not Modified,并告诉浏览器使用缓存资源,而不需要再次传输资源内容。

3. Last-Modified / If-Modified-Since

Last-Modified 是服务器返回的资源最后修改时间,If-Modified-Since 是浏览器在后续请求中发送的头信息,用于检查资源是否被修改。

  • 首次请求:服务器返回 Last-Modified 头,表示资源的最后修改时间。
  • 后续请求:浏览器发送 If-Modified-Since 头,请求服务器检查自上次修改后是否有更新。如果资源没有更新,服务器返回 304 Not Modified,浏览器使用缓存中的资源。

4. Expires

Expires 是 HTTP/1.0 中的缓存头,用来表示资源的过期时间。它的格式为一个绝对时间(GMT),例如 Expires: Wed, 21 Oct 2024 07:28:00 GMT。资源在这个时间点之前都是有效的,不需要重新请求服务器。

但是,由于 Expires 使用绝对时间,可能会出现时区问题或客户端时间与服务器时间不一致的问题,因此在现代开发中通常使用 Cache-Control: max-age 代替。

4. 缓存的工作流程

浏览器缓存的工作流程可以概括为以下几步:

  1. 首次请求

    • 用户第一次请求某个资源时,浏览器向服务器发送请求。
    • 服务器返回资源,并带有 Cache-ControlETagLast-Modified 等缓存相关的响应头。
    • 浏览器将资源及其缓存头信息存储在本地缓存中。
  2. 后续请求

    • 浏览器在再次请求同一个资源时,首先会检查本地缓存是否有该资源。

    • 如果缓存还在有效期内(如 Cache-Control: max-age 没过期),则直接从本地缓存读取资源,提升加载速度。

    • 如果缓存过期了或者需要进行验证(如 no-cache),浏览器会发送一个请求到服务器,带上 ETagIf-Modified-Since 等验证头。

    • 服务器检查资源是否更新:

      • 如果资源未修改,返回 304 Not Modified,浏览器继续使用本地缓存。
      • 如果资源已经修改,服务器返回新的资源,并更新浏览器缓存中的数据。

5. 缓存失效

缓存失效意味着缓存的资源已经过期或者不再被认为是有效的,导致浏览器需要重新请求服务器获取新的资源。以下是几种缓存失效的原因:

  • 缓存过期:当缓存头中指定的有效期(如 max-age)过期时,浏览器需要向服务器重新请求资源。
  • 服务器强制缓存失效:服务器可以通过设置 no-cacheno-store 来强制禁用缓存,或通过 ETag/Last-Modified 机制强制浏览器重新验证资源。
  • 用户手动刷新页面:用户按下浏览器的刷新按钮时,通常会忽略缓存,重新请求服务器资源。
  • 缓存策略更改:服务器修改了缓存策略(如更新了 Cache-ControlETag),也会导致缓存失效。

6. 缓存带来的优化与注意事项

  • 优化加载速度:缓存减少了重复的网络请求,减少了延迟,提升了网页的加载速度。
  • 减少带宽占用:通过缓存,服务器不需要每次都传输相同的资源,大大节约了带宽。
  • 缓存一致性问题:在使用缓存时,需要确保缓存的资源与服务器资源保持一致,否则用户可能会看到过期的内容。因此,需要合理配置缓存策略,结合 ETagLast-Modified 进行缓存验证。

总结:

  • 浏览器缓存的核心机制是根据资源的缓存策略,判断何时可以从本地缓存读取资源,何时需要重新请求服务器。
  • 常用的缓存策略包括 Cache-ControlETagLast-Modified 等。
  • 缓存不仅提升了用户体验,也减少了服务器的负载和网络带宽的使用,但需要根据具体需求合理配置,以确保缓存资源的有效性和一致性。