注册
web

浏览器缓存方案

一、浏览器缓存的核心作用与分类


作用:减少网络请求,提升页面加载速度,降低服务器压力。

分类



  1. 强缓存:浏览器直接从本地缓存获取资源,不发请求到服务器;
  2. 协商缓存:发送请求到服务器验证缓存是否有效,有效则返回304状态码,浏览器使用本地缓存。

二、强缓存实现方案(Cache-Control/Expires)


1. Cache-Control(HTTP/1.1,推荐)


  • 核心指令
    Cache-Control: max-age=31536000  // 缓存1年(单位:秒)
    Cache-Control: no-cache // 强制协商缓存
    Cache-Control: no-store // 禁止缓存
    Cache-Control: public/private // 缓存可见范围


  • 示例配置(Nginx)
    location ~* \.(js|css|png|jpg|jpeg|gif|svg)$ {
    expires 1y; // 等价于Cache-Control: max-age=31536000
    add_header Cache-Control "public";
    }



2. Expires(HTTP/1.0,兼容性好)


  • 格式
    Expires: Thu, 01 Jan 2024 00:00:00 GMT  // 绝对过期时间


  • 与Cache-Control的优先级

    • 若同时存在,Cache-Control 优先级更高(因 Expires 依赖服务器时间)。



三、协商缓存实现方案(Last-Modified/ETag)


1. ETag(推荐,更精准)


  • 原理:服务器为资源生成唯一标识(如文件哈希值),浏览器请求时通过 If--Match 发送标识,服务器对比后返回304(未修改)或200(修改)。
  • 示例流程

    1. 首次请求:服务器返回资源+ETag: "abc123"
    2. 再次请求:浏览器发送 If--Match: "abc123"
    3. 服务器对比标识,未修改则返回304,否则返回新资源。



2. Last-Modified/If-Modified-Since


  • 原理:服务器返回资源最后修改时间(Last-Modified),浏览器下次请求时通过 If-Modified-Since 发送时间,服务器对比后判断是否更新。
  • 缺点

    • 精度有限(仅精确到秒);
    • 无法检测文件内容未变但修改时间变更的情况(如编辑器自动保存)。



四、缓存策略对比表


策略强缓存协商缓存
核心字段Cache-Control/ExpiresETag/Last-Modified
是否发请求否(直接读本地)是(验证缓存有效性)
服务器压力中(需验证请求)
更新及时性差(需等max-age过期)好(每次请求验证)

五、各类资源的缓存策略


1. 静态资源(JS/CSS/图片)


  • 策略

    • 强缓存(max-age=31536000)+ 版本号(如 app.v1.0.0.js);
    • 版本更新时修改文件名,强制浏览器加载新资源。


  • Nginx配置
    location ~* \.(js|css|png|jpg|jpeg|gif|svg|woff|woff2|ttf|eot)$ {
    expires 1y;
    add_header Cache-Control "public, max-age=31536000";
    add_header ETag on; // 开启ETag协商缓存
    }



2. HTML页面


  • 策略

    • 不缓存或短缓存(max-age=0)+ 协商缓存(ETag);
    • 因HTML常包含动态内容,避免强缓存导致页面不更新。


  • 配置
    location / {
    expires 0;
    add_header Cache-Control "no-cache, no-store, must-revalidate";
    add_header Pragma "no-cache";
    }



3. 动态接口(API)


  • 策略

    • 禁止缓存(Cache-Control: no-cache);
    • 或根据业务需求设置短缓存(如5分钟)。



六、问题


1. 问:强缓存和协商缓存的执行顺序?




    1. 浏览器先检查强缓存(Cache-Control/Expires),有效则直接使用本地缓存;
    2. 强缓存失效后,发送请求到服务器验证协商缓存(ETag/Last-Modified),有效则返回304;
    3. 协商缓存失效后,服务器返回新资源(200 OK)。



2. 问:如何强制浏览器更新缓存?




    • 前端:修改资源URL(如加版本号 ?v=2.0);
    • 后端

      1. 发送 Cache-Control: no-cache 强制协商缓存;
      2. 更改 ETagLast-Modified 值,使协商缓存失效。





3. 问:ETag和Last-Modified的优缺点?




    • ETag

      ✅ 优点:精准检测资源变化(基于内容哈希);

      ❌ 缺点:计算哈希有性能开销,资源量大时影响服务器效率。
    • Last-Modified

      ✅ 优点:实现简单,服务器压力小;

      ❌ 缺点:精度低,无法检测内容未变但修改时间变更的情况。



4. 问:如何处理缓存导致的登录状态失效?




    • 在响应头中添加 Cache-Control: private(仅客户端可缓存);
    • 或对包含登录状态的资源设置 Cache-Control: no-cache,强制每次请求验证;
    • 前端路由跳转时,通过 window.location.reload(true) 强制刷新(跳过强缓存)。



七、缓存调试与优化工具



  1. Chrome DevTools

    • Network面板:查看请求的缓存状态(from disk cache/from memory cache/304 Not Modified);
    • 禁用缓存:勾选 Disable cache 可临时关闭缓存,方便开发调试。


  2. Lighthouse

    • 审计缓存策略是否合理,给出优化建议(如“可缓存的资源未设置缓存”)。


  3. 服务器日志

    • 分析 304 请求比例,评估缓存命中率(理想情况下静态资源命中率应>80%)。



作者:用户4081281200381
来源:juejin.cn/post/7522093523966197812

0 个评论

要回复文章请先登录注册