12-资源缓存策略:静态资源缓存、过期策略、提升小程序/后台访问速度

📅 发布时间:2026/8/25 1:15:32
12-资源缓存策略:静态资源缓存、过期策略、提升小程序/后台访问速度 12-资源缓存策略静态资源缓存、过期策略、提升小程序/后台访问速度一、浏览器缓存机制四种策略搞清楚用户打开小程序或后台管理系统加载速度很大程度上取决于缓存策略。缓存用得好二次访问秒开用不好要么用户看到旧数据要么每次都全量加载。浏览器缓存涉及4个核心 HTTP 头先理解它们各自的职责1. Cache-ControlHTTP/1.1优先级最高Cache-Control: max-age86400告诉浏览器这个资源缓存86400秒1天。在过期之前浏览器直接用本地缓存连请求都不发。常用值max-ageN缓存N秒no-cache不能用本地缓存每次必须向服务器验证no-store完全不缓存每次都重新下载public可以被CDN等中间节点缓存private只能被浏览器缓存CDN不缓存immutable资源永远不会变连验证都不用配合指纹化使用2. ExpiresHTTP/1.0老古董Expires: Wed, 11 Aug 2026 00:00:00 GMT指定一个绝对过期时间。现在基本被Cache-Control: max-age取代但作为兼容性兜底还保留着。如果同时存在Cache-Control优先。3. ETag内容指纹ETag: abc123服务器给每个资源生成一个唯一标识通常是文件内容的hash。浏览器下次请求时带上If-None-Match: abc123服务器对比ETag如果没变就返回304 Not Modified浏览器用本地缓存。4. Last-Modified最后修改时间Last-Modified: Mon, 10 Aug 2026 12:00:00 GMT服务器返回资源的最后修改时间。浏览器下次请求带上If-Modified-Since: Mon, 10 Aug 2026 12:00:00 GMT服务器判断如果在这个时间之后没改过返回304。强缓存 vs 协商缓存这四个头实际上是两套机制类型机制涉及头部效果强缓存过期前直接用本地缓存不发请求Cache-Control / Expires最快零网络开销协商缓存发请求问服务器能不能用旧的ETag / Last-Modified次快有网络往返但无数据传输优先级Cache-Control Expires ETag Last-Modified二、Nginx expires 配置Nginx 通过expires指令直接控制浏览器的Cache-Control和Expires头。server { listen 443 ssl; server_name static.vending.com; root /data/web/dist; # 图片、字体强缓存30天 location ~* \.(jpg|jpeg|png|gif|ico|webp|svg|woff|woff2|ttf|eot)$ { expires 30d; add_header Cache-Control public; } # CSS、JS强缓存7天 location ~* \.(css|js)$ { expires 7d; add_header Cache-Control public; } # HTML不缓存每次都拿最新的 location ~* \.(html|htm)$ { add_header Cache-Control no-cache, no-store, must-revalidate; expires off; } # JSON接口数据不缓存 location ~* \.json$ { add_header Cache-Control no-cache; expires off; } }expires 30d会在响应头中自动添加Cache-Control: max-age2592000和Expires头。三、静态资源指纹化哈希文件名 强缓存这里有个矛盾CSS/JS 设置强缓存7天但如果你发布了新版本用户浏览器里还是旧缓存怎么办答案就是指纹化——文件名中包含内容hash。/dist/js/app.a3b2c1d4.js /dist/js/app.b5e6f7g8.js ← 新版本hash不同就是新文件Webpack/Vue CLI 默认就做这个// vue.config.jsmodule.exports{filenameHashing:true,// 默认开启outputDir:dist,// 输出文件名带hashapp.[contenthash:8].js}这样配置后app.a3b2c1d4.js内容不变hash永远不变可以设强缓存1年代码更新后index.html引用的是app.b5e6f7g8.js新hash浏览器发现没见过这个文件重新下载index.html本身不缓存每次都拿最新的保证引用的JS文件名是最新的# 指纹化资源强缓存1年内容变了hash就变等于新URL location ~* \.([a-f0-9]{8})\.(js|css|png|jpg|jpeg|gif|webp|svg|woff2?)$ { expires 1y; add_header Cache-Control public, immutable; } # HTML入口文件绝对不能强缓存 location / { try_files $uri $uri/ /index.html; add_header Cache-Control no-cache, no-store, must-revalidate; expires off; }immutable关键字告诉浏览器这个资源永远不会变连协商验证都不用做。浏览器连304请求都省了性能拉满。四、分层缓存策略不同类型的资源缓存策略完全不同。整理成一张表资源类型缓存策略Cache-Controlexpires原因HTML不缓存no-cache, no-storeoff入口文件必须最新否则引用旧JS带hash的JS/CSS强缓存1年public, immutable, max-age315360001y内容变hash就变等于新文件带hash的图片/字体强缓存30天public, max-age259200030d商品图变更频率低API JSON不缓存no-cacheoff数据实时性要求高用户头像/动态图协商缓存no-cacheoff可能被用户更换需要验证第三方库CDN强缓存1年public, immutable1y版本固定不变核心原则能强缓存的尽量强缓存不能强缓存的用协商缓存实时数据不缓存。五、无人售货柜小程序缓存实战售货柜小程序使用 uni-app 开发打包后部署在 Nginx 上。完整配置server { listen 443 ssl http2; server_name m.vending.com; ssl_certificate /etc/nginx/ssl/vending.pem; ssl_certificate_key /etc/nginx/ssl/vending.key; root /data/web/miniapp; # 开启gzip压缩减小传输体积 gzip on; gzip_min_length 1k; gzip_comp_level 6; gzip_types text/plain text/css application/json application/javascript text/xml application/xml image/svgxml; gzip_vary on; # 带hash的静态资源强缓存1年 location ~* \.([a-f0-9]{6,8})\.(js|css|woff2?|ttf|eot|svg)$ { expires 1y; add_header Cache-Control public, immutable; access_log off; } # 商品图片强缓存7天 location ~* \.(jpg|jpeg|png|gif|webp|ico)$ { expires 7d; add_header Cache-Control public; access_log off; } # 首页HTML不缓存 location / { try_files $uri $uri/ /index.html; add_header Cache-Control no-cache, no-store, must-revalidate; expires off; } # API接口代理到后端不缓存 location /api/ { proxy_pass http://vending_backend; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; add_header Cache-Control no-cache; } }六、后台管理系统缓存实战后台管理系统用 Vue ElementUI 开发部署在同一台 Nginx 上server { listen 443 ssl http2; server_name admin.vending.com; ssl_certificate /etc/nginx/ssl/vending.pem; ssl_certificate_key /etc/nginx/ssl/vending.key; root /data/web/admin; # 带hash的静态资源 location ~* \.([a-f0-9]{6,8})\.(js|css|woff2?)$ { expires 1y; add_header Cache-Control public, immutable; access_log off; } # ElementUI图标字体 location ~* \.(woff2?|ttf|eot|svg)$ { expires 30d; add_header Cache-Control public; access_log off; } # HTML入口 location / { try_files $uri $uri/ /index.html; add_header Cache-Control no-cache, no-store, must-revalidate; expires off; } # 后台API location /api/ { proxy_pass http://admin_backend; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; add_header Cache-Control no-cache, no-store; # 后台实时数据接口设备在线状态、销售数据额外加no-store location ~* /api/realtime/ { proxy_pass http://admin_backend; add_header Cache-Control no-store; add_header Pragma no-cache; } } # 导出的Excel文件不缓存 location ~* /api/export/ { proxy_pass http://admin_backend; add_header Cache-Control no-store; add_header Content-Disposition $upstream_http_content_disposition; } }实时数据接口设备在线状态、销售看板加了no-store比no-cache更严格——浏览器连磁盘都不许写每次必须从服务器拿最新数据。导出 Excel 的接口也不缓存否则用户导出旧数据就尴尬了。七、缓存验证怎么确认配置生效配置完成后用 curl 验证响应头# 检查JS文件是否有强缓存头curl-Ihttps://m.vending.com/js/app.a3b2c1d4.js# 预期输出# HTTP/2 200# Cache-Control: public, immutable# Expires: Thu, 11 Aug 2027 00:00:00 GMT# Content-Encoding: gzip# 检查HTML是否不缓存curl-Ihttps://m.vending.com/# 预期输出# HTTP/2 200# Cache-Control: no-cache, no-store, must-revalidate# 模拟协商缓存验证第二次请求带ETagcurl-I-HIf-None-Match: abc123https://m.vending.com/js/app.a3b2c1d4.js# 如果ETag没变预期返回 304缓存策略不是配完就结束的定期检查X-Cache-Status和浏览器 Network 面板的Size列from disk cache / from memory cache 表示缓存命中持续优化才能保持最佳访问速度。缓存配置的本质是在数据新鲜度和访问速度之间找平衡——静态资源偏向速度强缓存动态数据偏向新鲜度不缓存找到这个平衡点系统体验就能上一个台阶。