说一下浏览器中的强缓存和协商缓存的区别

写在前面

对于一道高频的面试题,可能很多小伙伴还不知道这两者的概念,不知道是用来做什么的,以及有什么好处,强缓存和协商缓存是 Web 缓存机制的重要组成部分,它们在优化 Web 应用性能方面发挥了重要作用,接下来我们就来详细的聊一下吧!

强缓存

概念

强缓存指的是在缓存有效期内,不需要向服务器发送请求,直接从缓存中读取资源。这意味着在缓存有效期内,浏览器直接使用缓存的资源,不会与服务器通信。

好处

  1. 减少服务器负载:减少了不必要的请求,服务器负载显著降低。
  2. 提高页面加载速度:资源直接从本地缓存中读取,减少了网络延迟,页面加载速度更快。
  3. 节省带宽:避免重复下载相同的资源,节省了带宽资源。
  4. 改善用户体验:快速的页面加载提高了用户满意度和留存率。

如何开启

强缓存主要通过 HTTP 响应头中的 ExpiresCache-Control 属性来实现。这些属性是由服务器在响应中设置的,并指示浏览器如何缓存资源。

详细说明

Expires
  • 定义:一个绝对时间点,在此时间点之前,缓存的资源被认为是有效的。
  • 位置:响应头
  • 例子Expires: Wed, 21 Oct 2024 07:28:00 GMT

示例:

HTTP/1.1 200 OK
Expires: Wed, 21 Oct 2024 07:28:00 GMT
Content-Type: text/html
Content-Length: 1234
Cache-Control
  • 定义:更现代、更灵活的缓存控制方式,可以定义更细粒度的缓存策略。
  • 位置:响应头
  • 常用指令
    • max-age:相对时间,以秒为单位。例如:Cache-Control: max-age=3600 表示资源可以缓存 3600 秒(1 小时)。
    • no-cache:不使用强缓存,每次都要向服务器发送请求以确认资源是否改变。
    • no-store:不缓存资源,完全禁用缓存。
    • public:表示响应可以被任何缓存存储(包括浏览器和中间代理服务器)。
    • private:表示响应只能被单个用户的浏览器缓存,不允许代理缓存。

 示例:

HTTP/1.1 200 OK
Cache-Control: max-age=3600
Content-Type: text/html
Content-Length: 1234

协商缓存

概念

协商缓存需要客户端和服务器之间的交互。当缓存资源过期时,客户端会向服务器发送请求,服务器根据请求头中的信息判断客户端缓存的资源是否仍然有效。

好处

  1. 节省带宽:对于未修改的资源,服务器只返回状态码而不发送资源内容,节省了带宽。
  2. 减少延迟:即使需要与服务器通信,304 响应也比完全下载新的资源更快。
  3. 保持资源最新:确保浏览器使用的是最新版本的资源,提高了数据的一致性和可靠性。
  4. 平衡性能与新鲜度:在减少不必要请求的同时,确保资源的实时更新。

如何开启

协商缓存使用的主要属性是服务器返回的 Last-Modified ETag,而在下次请求时会使用 If-Modified-Since 和 If-None-Match,它们的值在实现协商缓存时起着关键作用。

详细说明

协商缓存相关属性:

Last-Modified:(服务器响应)

  • 含义: 资源的最后修改时间。
  • 格式: 一个 GMT 格式的时间字符串。
  • 示例: Last-Modified: Wed, 21 Oct 2015 07:28:00 GMT
  • 备注:和 If-Modified-Since 配合使用

If-Modified-Since:(请求头携带)

  • 含义: 客户端发送的请求头,其值通常是上次请求时服务器返回的 Last-Modified 值
  • 用途: 服务器根据这个值判断资源是否有更新。

ETag:(服务器响应)

  • 含义: 资源的唯一标识符,通常是资源内容的哈希值或版本号。
  • 示例: ETag: "33a64df551425fcc55e4d42a148795d9f25f89d4"
  • 备注:和 If-None-Match 配合使用

If-None-Match:(请求头携带,优先级更高)

  • 含义: 客户端发送的请求头,其值通常是上次请求时服务器返回的 ETag 值
  • 用途: 服务器根据这个值判断资源是否有更新。

协商缓存的工作流程

首次请求:浏览器请求资源,服务器返回资源内容以及 Last-Modified 和/或  ETag

HTTP/1.1 200 OK
Last-Modified: Wed, 21 Oct 2024 07:28:00 GMT
ETag: "abcd1234"
Content-Type: text/html
Content-Length: 1234

后续请求:浏览器再次请求该资源时,会带上 If-Modified-Since 和/或 If-None-Match 请求头。(当资源被缓存后,浏览器会根据之前服务器响应中的缓存头信息,在后续请求中自动添加这些请求头,以实现协商缓存机制。)

GET /index.html HTTP/1.1
Host: example.com
If-Modified-Since: Wed, 21 Oct 2024 07:28:00 GMT
If-None-Match: "abcd1234"

服务器响应:如果资源未修改,服务器返回 304 Not Modified 状态码,不包含消息体,浏览器继续使用缓存资源。

HTTP/1.1 304 Not Modified

如果资源已修改,服务器返回 200 OK 状态码和新的资源内容,同时更新 Last-Modified 和/或 ETag

优先级

  • 服务器首先会检查If-None-Match中的ETag值是否与服务器上该资源的当前ETag值匹配。
  • 如果ETag匹配成功(即资源内容未发生变化),服务器会返回304 Not Modified状态码,并结束响应,不再检查Last-Modified。
  • 如果ETag匹配失败(即资源内容可能发生变化),服务器会继续检查If-Modified-Since中的Last-Modified值(这提供了一个"双重检查"的机制,有助于在各种情况下优化资源传输)。
  • ETag 的优先级高于Last-Modified。这是因为 ETag 是基于资源内容生成的唯一标识符,能够更加准确地反映资源是否发生变化。而 Last-Modified 只是记录了资源最后修改的时间戳,可能会因为某些原因(如服务器时间设置不准确、文件被定期生成但内容未变等)而导致不准确。

综合对比

特性/机 制 强缓存 协商缓存
定义 浏览器直接从缓存中读取资源,无需与服务器通信 浏览器向服务器验证缓存资源的有效性
实现方式 HTTP 头信息中的 ExpiresCache-Control HTTP 头信息中的 Last-ModifiedETag
响应头 Expires, Cache-Control ETag, Last-Modified
请求头 无需特定请求头 If-None-Match, If-Modified-Since
匹配优先级 ETag 优先级高于 Last-Modified
匹配原理 根据缓存有效期直接使用缓存 浏览器发送上次接收的 ETagLast-Modified,服务器比较并返回 304 或 200
处理流程 浏览器检查缓存有效期,若有效直接使用 浏览器请求资源时,发送 If-None-MatchIf-Modified-Since,服务器根据 ETagLast-Modified 判断是否返回 304 或 200
典型场景 静态资源如图片、CSS、JS 文件 动态资源或频繁更新的资源
缓存控制 由浏览器控制,依赖于缓存策略和有效期 由服务器控制,通过生成和验证 ETagLast-Modified 实现
优先级处理 不涉及优先级 服务器优先检查 If-None-MatchETag 不匹配时直接返回 200,不再检查 If-Modified-Since
资源变化检测 依赖于缓存时间,不检测内容变化 基于内容 (ETag) 或修改时间 (Last-Modified) 检测资源变化
缓存策略 通过设置缓存有效期控制 通过服务器和浏览器间的缓存验证控制
优势 减少网络请求,提升加载速度 确保资源最新状态,节省带宽
劣势 可能使用过期的缓存,无法实时更新 增加请求开销,需要服务器支持

相关推荐

  1. 一下浏览器缓存协商缓存区别

    2024-07-11 21:38:07       24 阅读
  2. 缓存协商缓存区别

    2024-07-11 21:38:07       36 阅读
  3. 缓存协商缓存区别

    2024-07-11 21:38:07       36 阅读
  4. 浏览器缓存缓存主要区别

    2024-07-11 21:38:07       43 阅读
  5. (十三)缓存协商缓存区别

    2024-07-11 21:38:07       41 阅读
  6. 浏览器缓存协商缓存

    2024-07-11 21:38:07       55 阅读
  7. 前端缓存协商缓存

    2024-07-11 21:38:07       46 阅读
  8. 前端缓存协商缓存

    2024-07-11 21:38:07       29 阅读

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-07-11 21:38:07       66 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-07-11 21:38:07       70 阅读
  3. 在Django里面运行非项目文件

    2024-07-11 21:38:07       57 阅读
  4. Python语言-面向对象

    2024-07-11 21:38:07       68 阅读

热门阅读

  1. 【Redis 如何实现分级缓存】

    2024-07-11 21:38:07       19 阅读
  2. Rust开发环境搭建

    2024-07-11 21:38:07       24 阅读
  3. E10.【C语言】练习:编写一个猜数字游戏

    2024-07-11 21:38:07       19 阅读
  4. k8s 容器环境下的镜像如何转换为docker 使用

    2024-07-11 21:38:07       26 阅读
  5. 使用Apache Beam进行统一批处理与流处理

    2024-07-11 21:38:07       23 阅读
  6. 【LinuxC语言】手撕Http之处理POST请求

    2024-07-11 21:38:07       21 阅读
  7. 常用的简单的ps快捷键

    2024-07-11 21:38:07       19 阅读
  8. Bug汇总

    2024-07-11 21:38:07       20 阅读
  9. LVS集群(二)

    2024-07-11 21:38:07       22 阅读
  10. vscode连接unbuntu失败,显示Downloading vs code server...

    2024-07-11 21:38:07       19 阅读