面试官:不同刷新操作方式,对强制缓存和协商缓存的影响

面试导航 是一个专注于前、后端技术学习和面试准备的 免费 学习平台,提供系统化的技术栈学习,深入讲解每个知识点的核心原理,帮助开发者构建全面的技术体系。平台还收录了大量真实的校招与社招面经,帮助你快速掌握面试技巧,提升求职竞争力。如果你想加入我们的交流群,欢迎通过微信联系:yunmz777

强缓存和协商缓存基本概念

浏览器缓存是浏览器在本地存储用户最近请求的资源,以便在后续访问相同页面时能更快加载,提高性能并减少服务器负担。根据缓存策略,浏览器缓存可分为 强缓存 和 协商缓存:

  • 强缓存:浏览器在请求资源时,会根据响应头中的缓存策略判断是否直接使用本地缓存副本,而无需向服务器发送请求。如果资源符合强缓存规则,浏览器将直接从本地加载,避免网络请求,从而加快页面加载速度并降低服务器压力。

  • 协商缓存:当资源可能已过期或发生变化时,浏览器会向服务器发送请求,并附带特定的条件信息(如 ETagLast-Modified)。服务器根据这些信息判断资源是否更新,并返回相应的状态码。如果资源未修改,服务器返回 304 Not Modified,浏览器继续使用本地缓存;否则,服务器返回新的资源,浏览器更新缓存。

这种缓存机制能在保证资源最新性的同时,提高加载效率,优化用户体验。

浏览器缓存的主要优点包括以下几个方面:

  1. 提高页面加载速度:缓存可以让浏览器直接从本地加载资源,而无需重新请求服务器,减少网络延迟,使网页打开速度更快,提升用户体验。

  2. 降低服务器压力:通过缓存静态资源(如 CSS、JS、图片等),可以减少服务器的重复请求,降低带宽消耗和服务器负载,提升网站的可扩展性。

  3. 节省带宽:浏览器缓存减少了重复下载相同资源的需求,尤其在用户访问相同网站的多个页面时,可以显著降低流量消耗,提高访问效率。

  4. 支持离线访问:结合 Service Worker 缓存,浏览器可以在没有网络的情况下加载缓存的内容,使 PWA(渐进式 Web 应用)等离线体验更加流畅。

  5. 提升用户体验:页面加载速度更快、减少网络请求等待时间,以及支持离线访问,都能让用户获得更顺畅的浏览体验,提高网站的用户留存率。

  6. 提高资源利用率:对于较大的静态资源,如视频、字体、图片等,缓存可以避免重复下载,提高网络资源的利用效率,减少服务器和用户的资源开销。

通过合理的缓存策略,浏览器缓存能在 速度、流量、服务器负载和用户体验 之间取得平衡,使 Web 应用更加高效。

浏览器缓存,那它到底是缓存在哪里?

浏览器缓存主要存储在 内存磁盘,不同类型的缓存决定了数据的存储位置和存活时间。接下来我们将详细介绍各种缓存机制及其应用场景。

内存缓存(Memory Cache)

内存缓存将资源存储在 RAM 中,访问速度最快,适用于当前页面加载过程中频繁使用的资源,如 CSS、JS 和图片。它的生命周期较短,一旦页面关闭或刷新,部分缓存可能被释放。

特点:

  • 读取速度最快
  • 时效性短,随浏览器进程结束而释放
  • 容量有限,一般不会存储太大的资源
  • 常用于存储解码后的图片、CSS 样式表等

磁盘缓存(Disk Cache)

磁盘缓存将资源存储在本地硬盘上,适用于体积较大、生命周期较长的资源。相比内存缓存,它的访问速度稍慢,但能在浏览器关闭后仍然生效,减少后续请求。

特点:

  • 存储容量大
  • 持久化存储,重启浏览器后仍可使用
  • 适合存储较大文件
  • 通常会根据文件类型、资源大小等因素智能分配存储位置

Service Worker 缓存(Cache Storage)

Service Worker 提供了一种可编程的缓存方式,允许开发者手动管理缓存的资源,存储在 Cache Storage 中。

主要特性:

  • 支持离线访问能力
  • 可编程的缓存策略
  • 独立于主线程的后台运行
  • 网络代理能力
  • 常用于实现 PWA 应用

示例代码:

javascript 复制代码
// Service Worker 注册示例
if ("serviceWorker" in navigator) {
  navigator.serviceWorker
    .register("/sw.js")
    .then((registration) => {
      console.log("ServiceWorker registration successful");
    })
    .catch((err) => {
      console.log("ServiceWorker registration failed: ", err);
    });
}

HTTP 缓存

HTTP 缓存分为强缓存和协商缓存两种机制:

强缓存:

  • Cache-Control: 现代浏览器使用的主要机制

    • max-age:指定资源有效期
    • no-cache:强制验证缓存
    • no-store:禁止缓存
    • private/public:指定缓存作用域
  • Expires:早期的过期时间控制(已逐渐被 Cache-Control 取代)

协商缓存:

  • ETag/If-None-Match:基于资源内容的验证

  • Last-Modified/If-Modified-Since:基于时间的验证

DNS 缓存

DNS 缓存分为多个层级:

  • 浏览器 DNS 缓存
  • 操作系统 DNS 缓存
  • 路由器 DNS 缓存
  • ISP DNS 缓存

可以通过以下 DNS 预解析来优化:

html 复制代码
<link rel="dns-prefetch" href="//example.com" />

预解析/预加载缓存(Prefetch / Preload)

现代浏览器提供了多种资源预加载机制:

  • preload:当前页面必需资源
html 复制代码
<link rel="preload" href="style.css" as="style" />
  • prefetch:未来页面可能需要的资源
html 复制代码
<link rel="prefetch" href="next-page.js" />
  • preconnect:提前建立连接
html 复制代码
<link rel="preconnect" href="https://example.com" />

浏览器会根据资源类型、使用频率和缓存策略来决定数据的存储位置,以平衡访问速度和存储效率。合理利用各种缓存机制,可以显著提升网站性能和用户体验。

强缓存和协商缓存工作流程

首先我们先栏看强缓存和协商缓存的工作流程图,如下所示:

当浏览器请求资源(如 HTML、CSS、JS、图片等)时,会先检查缓存,决定是直接使用缓存还是向服务器请求新资源。整个缓存机制主要分为 强缓存协商缓存 两种策略。

强缓存 (Freshness)

强缓存是指在本地缓存资源未过期的情况下,浏览器直接使用缓存,不发送请求给服务器,提高访问速度。

浏览器根据 Cache-ControlExpires 头信息判断缓存是否仍然有效:

  • Cache-Control: max-age=3600:表示资源在 3600 秒(即 1 小时)内有效,不需要重新请求服务器。

  • Expires: Wed, 21 Oct 2025 07:28:00 GMT:资源的绝对过期时间,若未超过此时间,直接使用缓存。

主要的处理流程如下:

  1. 浏览器请求资源后,若 Cache-ControlExpires 指示缓存仍有效,则直接从缓存读取资源,无需网络请求。
  2. 若缓存过期,则进入 协商缓存 阶段。

协商缓存 (Revalidation)

如果强缓存失效,浏览器不会立即下载新资源,而是向服务器发起 条件请求,询问资源是否发生了变化,服务器通过特定头信息返回是否需要更新。

ETag 校验

ETag 是服务器生成的资源唯一标识符,若资源修改,ETag 也会更新。

请求流程:

  1. 浏览器请求资源时,服务器返回资源及 ETag 值,例如:

    vbnet 复制代码
    ETag: "abc123"
  2. 资源缓存后,浏览器下次请求时,在请求头中添加:

    sql 复制代码
    If-None-Match: "abc123"
  3. 服务器接收请求后:

    • ETag 未变 (资源未修改),返回 304 Not Modified,浏览器直接使用缓存。

    • ETag 变化 (资源已修改),返回 200 OK,并提供新资源。

Last-Modified 校验

若服务器未使用 ETag,浏览器会改用 Last-Modified 进行时间校验。

请求流程:

  1. 服务器首次返回资源时,包含 Last-Modified 头,例如:

    yaml 复制代码
    Last-Modified: Tue, 12 Mar 2024 10:00:00 GMT
  2. 浏览器下次请求时,在请求头中携带:

    yaml 复制代码
    If-Modified-Since: Tue, 12 Mar 2024 10:00:00 GMT
  3. 服务器接收请求后:

    • 若资源未修改 (时间未变),返回 304 Not Modified,浏览器使用缓存。

    • 若资源已修改 (时间更新),返回 200 OK,并提供新资源。

服务器响应

服务器根据 ETagLast-Modified 进行校验后,返回相应的状态码:

状态码 含义
200 OK 资源有更新,返回新内容,并更新 ETagLast-Modified
304 Not Modified 资源未更改,浏览器使用缓存,不返回内容。

304 返回时,浏览器不会重新下载资源,只会复用本地缓存文件,从而节省带宽。

关键缓存字段

其中,在上面的流程中,又有几个令人难懂的字段,如下:

头部字段 作用
ETag 资源唯一标识,变化表示资源已修改。
Expires 绝对过期时间,浏览器用于强缓存判断。
Cache-Control 详细缓存策略,如 max-ageno-cachemust-revalidate
Last-Modified 资源最后修改时间,用于协商缓存判断。
If-None-Match 浏览器携带 ETag 进行验证,匹配则返回 304
If-Modified-Since 浏览器携带 Last-Modified 进行验证,时间一致则返回 304

小结

  1. 强缓存 (Cache-Control / Expires):如果资源未过期,直接从缓存加载,无需请求服务器。

  2. 协商缓存 (ETag / Last-Modified):如果缓存过期,浏览器询问服务器资源是否更新:

    • ETag 优先 (更精准),匹配则 304

    • ETag 时,用 Last-Modified ,时间一致则 304

  3. 最终处理

    • 304 Not Modified:浏览器使用缓存,无需重新下载资源。

    • 200 OK:服务器返回新资源,并更新缓存策略。

这样既减少了服务器请求次数,也保证了资源的最新状态,提升了性能和用户体验。

图解强缓存和协商缓存

在上面的内容中讲了这么多的理论, 你是否还是不太理解什么是 强缓存协商缓存 啊,那么接下来我们就用几张图片来弄清楚这两者的区别。

强缓存

强缓存就是文件直接从本地缓存中获取,不需要发送请求。

首次请求

当浏览器发送初次请求时,浏览器会向服务器发起请求,服务器接收到浏览器的请求后,返回资源并返回一个 Cache-Control 字段给客户端,在该字段中设置一些缓存相关的信息,例如最大过期时间。

再次请求

在前面的基础上,浏览器再次发送请求,浏览器一节接收到 Cache-Control 的值,那么这个时候浏览器它会首先检查它的 Cache-Control 是否过期,如果没有过期则直接从本地缓存中拉取资源,返回割到客户端,则无需再经过服务器。

缓存失效

强缓存有过期时间,那么就意味着总有一天缓存会失效,如果客户端的 Cache-Control 失效了,那么它就会像首次请求中一样,重新向服务器发起请求,之后服务器会再次返回资源和 Cache-Control 的值。

协商缓存

协商缓存也叫做对比缓存,服务端判断客户端的资源是否和服务端的一样,如果一样则返回 304,反之返回 200 和最新的资源。

初次请求

如果客户端是第一次向服务器发出请求,则服务器返回资源和对应的资源标识给浏览器,该资源标识就是对当前所返回资源的唯一标识,可以是 ETag 或者是 Last-Modified

之后如果浏览器再次发送请求是,浏览器就会带上这个资源表,此时服务端就会通过这个资源标识,可以判断出浏览器的资源跟服务器此时的资源是否一致,如果一致则返回 304 Not Modified,如果不一致,则返回 200,并返回资源以及新的资源标识。

不同刷新操作方式,对强制缓存和协商缓存的影响

普通刷新(F5 或点击刷新按钮)

  1. 强制缓存(Cache-Control / Expires):如果缓存未过期,浏览器直接使用缓存;如果缓存过期,则进入协商缓存流程。
  2. 协商缓存(ETag / Last-Modified) :如果强缓存过期,浏览器向服务器发送 If-Modified-SinceIf-None-Match 头,服务器检查资源是否更新:
    • 未修改 :返回 304 Not Modified,浏览器使用缓存数据。
    • 已修改 :返回 200 OK,并提供新资源。
  3. 服务器负担:如果缓存命中,则负担较小;如果缓存过期,则需要服务器参与协商缓存。

强制刷新(Ctrl + F5 或 Shift + 刷新按钮)

  1. 强制缓存 :浏览器忽略所有缓存策略,无论 Cache-ControlExpires 是否有效,都会直接向服务器请求最新资源。
  2. 协商缓存 :浏览器不会发送 If-Modified-SinceIf-None-Match,直接获取完整的新资源。
  3. 服务器负担:最大,所有资源都会重新下载。

地址栏回车

  1. 强制缓存:如果缓存未过期,直接使用缓存;如果缓存过期,则进入协商缓存流程。
  2. 协商缓存 :如果强缓存失效,浏览器会向服务器发送 If-Modified-SinceIf-None-Match 进行协商缓存验证。
  3. 服务器负担:和普通刷新类似,适中。

前进 / 后退

  1. 强制缓存 :通常使用 Memory Cache(内存缓存),如果页面仍在内存中,不会向服务器请求,直接使用缓存数据。
  2. 协商缓存 :通常不会触发请求,即使缓存过期,浏览器仍可能直接使用 Memory CacheDisk Cache
  3. 服务器负担:最小,几乎不产生额外的服务器请求。

清空缓存后刷新

  1. 强制缓存:缓存已清空,浏览器没有可用的缓存数据,必须重新向服务器请求所有资源。
  2. 协商缓存:由于无缓存数据可用于协商,所有请求都需要服务器返回完整资源。
  3. 服务器负担:最大,等同于用户首次访问网站。

小结

刷新方式 强制缓存 协商缓存 服务器负担
F5 可能使用 失效时生效,返回 304200 适中
Ctrl + F5 跳过缓存,直接请求服务器 跳过协商缓存,请求最新资源
地址栏回车 可能使用 失效时生效,返回 304200 适中
前进 / 后退 直接使用 Memory Cache 很少触发
清空缓存后刷新 不使用,直接请求 不使用,直接请求

不同刷新方式的应用场景:

  1. 普通刷新(F5) 适用于检查页面是否有更新,同时减少不必要的服务器请求。

  2. 强制刷新(Ctrl + F5) 适用于确保获取最新内容,如前端开发调试或页面异常。

  3. 地址栏回车 适用于正常访问网站,与 F5 类似。

  4. 前进 / 后退 适用于快速浏览历史页面,提高页面切换速度。

  5. 清空缓存后刷新 适用于解决缓存导致的问题,如 CSS/JS 资源未更新。

合理利用不同的刷新方式可以提高页面加载速度,同时减少服务器负担。

总结

强缓存 (本地缓存)是指在资源的缓存有效期内,浏览器无需向服务器发送请求,直接使用本地缓存的数据,提高页面加载速度,减少网络请求。它主要依赖 Cache-Control: max-ageExpires 头信息来控制资源的有效期,当缓存未过期时,浏览器不会发起请求。

协商缓存 (条件请求)是在强缓存失效后,浏览器向服务器发送请求,并携带 ETagLast-Modified 进行资源校验。服务器通过比对 ETagLast-Modified 判断资源是否更新,若资源未变更,则返回 304 Not Modified,浏览器继续使用缓存,否则返回 200 OK 并提供新资源。

两者结合使用可以优化网页加载性能,减少服务器压力,同时确保数据的时效性。

相关推荐
C_V_Better17 分钟前
浏览器缓存机制:JavaScript 文件缓存导致 404 错误的解决方案
开发语言·前端·javascript·缓存
小救星小杜、20 分钟前
a = b &&c 的含义
开发语言·前端·javascript
uhakadotcom21 分钟前
Traefik:简化微服务部署的现代反向代理
后端·面试·github
uhakadotcom21 分钟前
Babylon.js:轻松打造Web 3D体验
前端·javascript·面试
parade岁月23 分钟前
告别代码质量隐患:Husky 生态工具链在前端工程化中的实战应用
前端·javascript
小成C23 分钟前
为什么会演化出RSC,SSR和RSC关系大解密
前端·react.js
程序员的勇敢24 分钟前
MCP-Playwright:AI自动化神器,可执行JS代码进行复杂交互任务!
后端
过期的H2O224 分钟前
【H2O2 | 软件开发】Axios发送Http请求
前端·http·axios·交互
bug总结30 分钟前
vue3 public下引入图片路径打包后线上不显示问题解决
前端·javascript·vue.js
悠然青年帅33 分钟前
基于Vue+Canvas实现的画板绘画以及保存功能
前端