陌上人如玉
公子世无双

HTTP强缓存与协商缓存全解析:原理、区别、实践与优化

HTTP 缓存是前端性能优化的核心手段,能大幅减少重复请求、降低服务器压力、提升页面加载速度。其中强缓存协商缓存是最基础、最常用的两种缓存策略,本文从原理、区别、使用、优化四个维度彻底讲透。

一、前言:HTTP 缓存整体流程

浏览器请求资源时,会按先强缓存 → 后协商缓存的顺序判断:
1. 先检查强缓存:生效 → 直接使用本地缓存,不发请求
2. 强缓存失效 → 发起协商缓存请求:服务器校验通过 → 使用缓存(304),否则返回新资源(200)

二、强缓存:无需请求服务器,直接读本地

1. 核心定义

强缓存是最激进的缓存策略:浏览器判断本地缓存未过期时,完全不向服务器发送请求,直接从内存(Memory Cache)或磁盘(Disk Cache)读取资源。

2. 关键响应头

强缓存有两个控制头,HTTP1.1 的 Cache-Control 优先级高于 HTTP1.0 的 Expires

(1)Expires(HTTP1.0,已不推荐)

  • 格式:响应头返回绝对时间
  • 原理:浏览器对比本地时间与该时间,未到则使用缓存
  • 缺陷:依赖客户端本地时间,时间被修改会导致缓存失效/错乱
Expires: Wed, 03 Mar 2026 12:00:00 GMT

(2)Cache-Control(HTTP1.1,主流方案)

  • 格式:返回相对时间(秒),不受本地时间影响
  • 常用取值:
    含义
    max-age=xxx 缓存有效期,如 max-age=31536000(1年)
    public 所有节点(浏览器+CDN)均可缓存
    private 仅浏览器可缓存(默认值)
    no-cache 不直接使用强缓存,强制走协商缓存
    no-store 完全不缓存,每次都请求新资源
    s-maxage=xxx 仅CDN等代理服务器生效,优先级高于max-age
Cache-Control: max-age=31536000, public

3. 表现特征

  • Network 面板:Size 列显示 (from memory cache)/(from disk cache)
  • 状态码:无请求,无状态码
  • 优势:速度最快,零请求开销

三、协商缓存:发请求校验,服务器决定是否用缓存

1. 核心定义

强缓存失效后,浏览器会携带缓存标识向服务器发请求,服务器校验资源是否更新:
– 未更新 → 返回 304 Not Modified,浏览器用本地缓存
– 已更新 → 返回 200 OK + 新资源

2. 两组缓存标识(二选一,ETag 优先级更高)

(1)Last-Modified + If-Modified-Since(时间戳)

  • 响应头:Last-Modified 服务器返回资源最后修改时间
  • 请求头:If-Modified-Since 浏览器携带上次的修改时间
  • 原理:服务器对比时间,未变则返回304
  • 缺陷:
    1. 仅精确到,秒内多次修改无法识别
    2. 文件内容不变但修改时间改变,会误判为新资源
// 响应
Last-Modified: Tue, 02 Mar 2026 10:00:00 GMT

// 请求
If-Modified-Since: Tue, 02 Mar 2026 10:00:00 GMT

(2)ETag + If-None-Match(文件指纹,推荐)

  • 响应头:ETag 服务器根据文件内容生成唯一哈希值(指纹)
  • 请求头:If-None-Match 浏览器携带上次的ETag
  • 原理:服务器对比指纹,完全一致则返回304
  • 优势:精准识别文件内容变化,不受时间影响
// 响应
ETag: "5f3d2a1b-1234"

// 请求
If-None-Match: "5f3d2a1b-1234"

3. 表现特征

  • Network 面板:有请求,状态码为 304 Not Modified
  • 优势:比强缓存灵活,比无缓存省流量(仅返回响应头,无响应体)

四、强缓存 vs 协商缓存:核心区别与联系

1. 核心区别(表格版,适合博客展示)

维度 强缓存 协商缓存
是否发请求 不发请求 发请求(仅头部,无资源体)
状态码 无请求,无状态码 304(命中)/200(未命中)
控制头 Expires、Cache-Control Last-Modified/ETag
优先级 高于协商缓存 强缓存失效后才触发
性能 最优 次之
灵活性 差(到期前无法更新) 高(服务器实时校验)

2. 二者联系

  1. 同属 HTTP 缓存:目标都是减少资源传输,提升加载速度
  2. 执行顺序固定:先校验强缓存,失效后再走协商缓存
  3. 互补使用:静态资源用强缓存,动态页面用协商缓存

五、实战使用:Nginx 配置 + 前端最佳实践

1. Nginx 缓存配置示例

区分静态资源(强缓存)和HTML(协商缓存),是前端最常用方案:

server {
    # 1. JS/CSS/图片/字体:强缓存1年 + ETag协商兜底
    location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg|woff2)$ {
        expires 1y; # 强缓存1年
        etag on;    # 开启ETag
        add_header Cache-Control "public, max-age=31536000";
    }

    # 2. HTML:禁用强缓存,强制协商缓存
    location ~* \.html$ {
        add_header Cache-Control "no-cache";
        etag on;
        expires -1; # 禁止强缓存
    }
}

2. 前端工程化配合

  • 静态资源(JS/CSS/图片):webpack/vite 打包加 hash 后缀(如 app.abc123.js
  • 原理:文件内容变化 → hash 变化 → 视为新资源,强缓存自动失效
  • 优势:既享受长时强缓存,又能实时更新

六、缓存优化与避坑注意点

1. 资源分类策略(核心)

  • 静态资源(不变/少变):长时强缓存 + hash 命名
  • HTML(入口文件):协商缓存(no-cache)
  • 接口数据:按需缓存,敏感数据用 no-store

2. 头优先级必记

  1. Cache-Control > Expires
  2. ETag > Last-Modified
  3. 同时配置时,只生效优先级高的

3. 易混淆概念澄清

  • no-cache ≠ 不缓存:是跳过强缓存,直接走协商缓存
  • no-store = 真不缓存:本地和服务器都不存储
  • 不要给所有资源加 no-cache,会浪费协商缓存请求

4. 性能与精准平衡

  • 大文件:关闭 ETag(哈希计算耗性能),用 Last-Modified 即可
  • CDN 场景:加 s-maxage 控制代理缓存,避免CDN缓存过时资源
  • 移动端:优先内存缓存,max-age 不宜过短(减少请求)

5. 调试技巧

  • Chrome DevTools → Network:
    • Size 列:memory/disk cache = 强缓存命中
    • Status 列:304 = 协商缓存命中
  • 禁用缓存:勾选 Disable Cache,调试时用

七、总结

  1. 强缓存:不发请求,靠 Cache-Control 控制,速度最快,适合带hash的静态资源
  2. 协商缓存:发请求校验,靠 ETag/Last-Modified 控制,灵活精准,适合HTML
  3. 执行顺序:强缓存优先 → 失效走协商缓存
  4. 最佳实践:静态资源长强缓存+hash,HTML协商缓存,兼顾性能与更新

HTTP 缓存是前端必知必会的基础知识点,合理配置能让页面加载速度提升50%以上,是面试和工程优化的高频考点。

赞(0) 打赏
未经允许不得转载:陌上寒 » HTTP强缓存与协商缓存全解析:原理、区别、实践与优化

评论 抢沙发

觉得文章有用就打赏一下文章作者

非常感谢你的打赏,我们将继续给力更多优质内容,让我们一起创建更加美好的网络世界!

微信扫一扫

支付宝扫一扫