【代码优化篇】强缓存和协商缓存

强缓存和协商缓存

一、强缓存与协商缓存的区别

强缓存 :浏览器直接读取本地缓存,不发送请求到服务器。通过 Cache-Control 或 Expires 响应头实现。
协商缓存 :浏览器发送请求到服务器,由服务器判断资源是否过期。通过 ETag/If-None-Match 或 Last-Modified/If-Modified-Since 实现。


二、Vue2 前端实现强缓存(静态资源)

步骤:

  1. 打包生成哈希文件名 :Vue2 默认在 webpack 配置中为文件名添加 contenthash,如 app.a1b2c3.js。
  2. 服务器配置强缓存头 :在 Nginx/CDN 中为静态资源设置 Cache-Control: max-age=31536000(1年)。

示例 Nginx 配置:

nginx 复制代码
location /static {
    alias /path/to/static;
    expires 1y; # 等效于 Cache-Control: max-age=31536000
    add_header Cache-Control "public";
}

三、Spring Boot 后端实现协商缓存(动态接口)

步骤:

  1. 添加 ETag 支持 :使用 ShallowEtagHeaderFilter 自动生成 ETag。
  2. 返回带缓存控制的响应 :手动设置 Cache-Control 头。

示例代码:

java 复制代码
import org.springframework.context.annotation.Configuration;
import org.springframework.web.filter.ShallowEtagHeaderFilter;
import org.springframework.http.CacheControl;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.Filter;
import java.util.concurrent.TimeUnit;

@Configuration
public class WebConfig {
    public Filter etagFilter() {
        return new ShallowEtagHeaderFilter();
    }
}

@RestController
public class ApiController {
    
    // 协商缓存示例(自动 ETag)
    @GetMapping("/user")
    public ResponseEntity<User> getUser() {
        User user = userService.findUser();
        return ResponseEntity.ok()
                .cacheControl(CacheControl.maxAge(30, TimeUnit.MINUTES)) // 建议缓存但需要验证
                .body(user);
    }
    
    // 强缓存示例(慎用)
    @GetMapping("/static-data")
    public ResponseEntity<String> getStaticData() {
        return ResponseEntity.ok()
                .cacheControl(CacheControl.maxAge(7, TimeUnit.DAYS)) // 强缓存7天
                .body("Immutable Data");
    }
}

四、测试缓存效果

  1. 强缓存:

    • 首次请求:返回 200 OK,响应头包含 Cache-Control: max-age=31536000。
    • 再次请求:浏览器直接读取缓存,状态为 200 (from disk cache)。
  2. 协商缓存:

    • 首次请求:返回 200 OK,响应头包含 ETag: "a1b2c3"。
    • 再次请求:请求头携带 If-None-Match: "a1b2c3",若未修改,服务器返回 304 Not Modified。

五、注意事项

  • 前端静态资源:确保文件名哈希变化,避免旧缓存影响新版本。
  • 动态接口 :敏感数据避免使用强缓存,优先用 no-cache 或 private。
  • 测试工具:使用浏览器开发者工具的 Network 面板检查响应头与缓存状态。

总结 :强缓存通过设置长时间 max-age 实现,适用于静态资源;协商缓存通过 ETag/Last-Modified 验证,适用于动态数据。Vue2 利用打包哈希 + 服务器配置,Spring Boot 通过响应头控制实现。

相关推荐
Alluxio11 小时前
Alluxio + OCI:为 AI 工作负载实现亚毫秒访问延迟与可扩展吞吐
运维·数据库·人工智能·分布式·缓存·ai·语言模型
青瓦梦滋16 小时前
Redis主从复制
服务器·数据库·redis·缓存·bootstrap
衡石科技1 天前
兼顾查询速度与数据时效:衡石的缓存和分析加速
缓存·数据缓存·数据时效
瑞克-桑切斯2 天前
redis
数据库·redis·缓存
我是大猴子2 天前
redis
数据库·redis·缓存
code2cat2 天前
【随笔】推理准入控制:请求进来之前,先给KV缓存留出位置
缓存·大语言模型·vllm
徐小黑ACG3 天前
Redis-基础
数据库·redis·缓存
FungLeo3 天前
成为全栈·基础补充·缓存的层次与失效:浏览器、CDN、服务端、数据库
缓存·cdn·数据一致性·http缓存·成为全栈·flutter缓存
code2cat4 天前
【随笔】KV缓存量化:省下的显存,要付出多少数值误差
人工智能·缓存·大语言模型
csdn_aspnet4 天前
Redis 入门:Windows、Mac安装指南
数据库·windows·redis·缓存·mac