前端知识速记:浏览器缓存机制 - 强缓存与协商缓存

前端知识速记:浏览器缓存机制 - 强缓存与协商缓存


浏览器缓存是提升Web应用性能的关键技术之一。通过将静态资源(如CSS、JavaScript、图片等)存储在浏览器本地,可以避免重复从服务器下载,显著减少页面加载时间,改善用户体验。

一、浏览器缓存机制概述

浏览器缓存主要分为两种:强缓存 (也称为本地缓存)和 协商缓存(也称为弱缓存)。

  • 强缓存: 当浏览器请求资源时,首先检查本地缓存是否命中。如果命中,则直接从缓存中读取资源,无需向服务器发送任何请求。
  • 协商缓存: 当强缓存未命中时,浏览器会向服务器发送请求,询问服务器资源是否发生变化。如果服务器告知资源未改变,则浏览器从缓存中读取资源;如果服务器告知资源已改变,则浏览器会下载新资源并更新缓存。

二、强缓存(Local Cache)

强缓存通过 HTTP 响应头中的 Cache-ControlExpires 字段来控制。

1. Cache-Control

Cache-Control 是一个更加现代且功能强大的缓存控制字段。它支持多种指令,常见的包括:

  • max-age=<seconds>: 指定资源被缓存的最大时间,单位为秒。例如,Cache-Control: max-age=3600 表示资源可以被缓存 1 小时。
  • s-maxage=<seconds>: 类似于 max-age,但只对共享缓存(例如 CDN)有效。
  • private: 表示资源只能被用户私有的浏览器缓存,不允许被共享缓存。
  • public: 表示资源可以被任何缓存(包括私有缓存和共享缓存)缓存。
  • no-cache: 强制浏览器进行协商缓存,即每次使用缓存资源前都需要向服务器确认资源是否过期。 虽然名字叫 no-cache,但实际上仍然允许浏览器缓存资源。
  • no-store: 禁止浏览器和所有中间缓存存储任何版本的响应。 资源不进行缓存。

示例:

http 复制代码
HTTP/1.1 200 OK
Content-Type: image/jpeg
Cache-Control: max-age=86400, public

上述响应头表示该图片资源可以被缓存 24 小时,并且可以被任何缓存(包括 CDN)缓存。

2. Expires

Expires 指定资源失效的绝对时间,是一个日期时间字符串。 Expires 基于客户端时间,因此如果客户端时间与服务器时间不同步,可能会导致缓存失效。

示例:

http 复制代码
HTTP/1.1 200 OK
Content-Type: image/jpeg
Expires: Thu, 01 Dec 2023 16:00:00 GMT

上述响应头表示该图片资源在 2023 年 12 月 1 日 16:00:00 GMT 之后失效。

注意: 如果同时设置了 Cache-ControlExpiresCache-Control 的优先级更高。

三、协商缓存(Conditional Cache)

当强缓存未命中时,浏览器会向服务器发送请求,通过 If-Modified-SinceIf-None-Match 请求头询问服务器资源是否发生变化。服务器根据请求头中的信息判断资源是否过期,并返回相应的状态码和响应头。

1. Last-ModifiedIf-Modified-Since

  • Last-Modified: 服务器在响应头中返回资源的最后修改时间。
  • If-Modified-Since: 浏览器在请求头中携带上次服务器返回的 Last-Modified 值,询问服务器资源自该时间以来是否发生变化。

流程:

  1. 浏览器第一次请求资源时,服务器返回 Last-Modified 响应头。
  2. 浏览器再次请求该资源时,会在请求头中携带 If-Modified-Since,值为上次响应的 Last-Modified 值。
  3. 服务器比较 If-Modified-Since 与资源的最后修改时间:
    • 如果资源未修改,则返回 304 Not Modified 状态码,不返回资源内容。
    • 如果资源已修改,则返回 200 OK 状态码,并返回新的资源内容和新的 Last-Modified 值。

示例:

第一次请求:

http 复制代码
HTTP/1.1 200 OK
Content-Type: image/jpeg
Last-Modified: Tue, 21 Nov 2023 10:00:00 GMT

第二次请求:

http 复制代码
GET /image.jpg HTTP/1.1
If-Modified-Since: Tue, 21 Nov 2023 10:00:00 GMT

服务器响应(资源未修改):

http 复制代码
HTTP/1.1 304 Not Modified

2. ETagIf-None-Match

  • ETag: 服务器为资源生成的唯一标识符,可以是资源的哈希值或其他算法生成的值。
  • If-None-Match: 浏览器在请求头中携带上次服务器返回的 ETag 值,询问服务器资源是否发生变化。

流程:

  1. 浏览器第一次请求资源时,服务器返回 ETag 响应头。
  2. 浏览器再次请求该资源时,会在请求头中携带 If-None-Match,值为上次响应的 ETag 值。
  3. 服务器比较 If-None-Match 与资源的 ETag 值:
    • 如果 ETag 值相同,则返回 304 Not Modified 状态码,不返回资源内容。
    • 如果 ETag 值不同,则返回 200 OK 状态码,并返回新的资源内容和新的 ETag 值。

示例:

第一次请求:

http 复制代码
HTTP/1.1 200 OK
Content-Type: image/jpeg
ETag: "637F7F7F7F7F7F7F"

第二次请求:

http 复制代码
GET /image.jpg HTTP/1.1
If-None-Match: "637F7F7F7F7F7F7F"

服务器响应(资源未修改):

http 复制代码
HTTP/1.1 304 Not Modified

注意: ETagLast-Modified 更精确,因为 ETag 可以检测到即使资源内容没有变化,但最后修改时间发生了变化的情况。 如果同时设置了 Last-ModifiedETag,服务器会优先验证 ETag

四、实际应用场景

  • 图片、CSS、JavaScript 等静态资源: 可以使用强缓存,设置较长的 max-age 值。
  • HTML 文件: 通常使用协商缓存,确保用户总是获取到最新的页面内容。
  • API 接口: 可以根据 API 的特性选择合适的缓存策略。

五、强缓存与协商缓存对比

特性 强缓存 (Local Cache) 协商缓存 (Conditional Cache)
控制字段 Cache-Control, Expires Last-Modified/If-Modified-Since, ETag/If-None-Match
请求服务器 无需请求服务器 需要请求服务器进行验证
状态码 200 OK (from cache) / 200 OK (来自内存/硬盘缓存) 304 Not Modified (使用缓存) / 200 OK (返回新资源)
资源新鲜度判断 基于过期时间和客户端时间 基于服务器资源是否发生变化
适用场景 静态资源,不经常变化的资源 动态资源,需要验证新鲜度的资源
优先级 低,在强缓存失效后才会生效
相关推荐
悠悠:)11 分钟前
LogicFlow自定义节点:矩形、HTML(vue3)
前端·react.js·前端框架
水水阿水水11 分钟前
第二章:QT核心机制(二)
服务器·前端·c++·qt
UncaughtError26 分钟前
Langchain.js 入门及应用:HelloWorld、模型集成、PromptTemplate、LangSmith
前端
haomo20141 小时前
AI时代下的安全堡垒:零信任模式如何守护你的AI系统
前端·人工智能·信息可视化
CodePencil1 小时前
HTML专题之语义化
前端
小九九的爸爸2 小时前
React用过是吧,请说一下setState的大致流程...
前端·react.js·面试
录大大i2 小时前
HTML之JavaScript分支结构
前端·javascript·html
阿珊和她的猫2 小时前
ESLint 如何处理 ES6+ 语法
前端·es6·状态模式
九河云2 小时前
华为云的分布式缓存服务适合什么场景
分布式·缓存·华为云
呀啊~~2 小时前
【前端框架与库】「React 全面解析」:从 JSX 语法到高阶组件,深度剖析前端开发中的核心概念与最佳实践
前端·javascript·学习·react.js·前端框架