Nginx 缓存策略配置方案对比
·
为什么要配置缓存策略
SPA 应用(Vue/React/uni-app H5)打包后,静态资源(JS/CSS/图片)的文件名通常包含内容 hash(如 index-a3f2b1.js)。合理配置缓存策略可以带来以下收益:
配置缓存的优势
| 优势 | 说明 |
|---|---|
| 提升页面加载速度 | 带 hash 的 JS/CSS/图片缓存到浏览器,二次访问无需重新下载,加载速度提升 50%-80% |
| 降低服务器带宽 | 静态资源命中浏览器缓存后不再请求服务器,减少流量消耗 |
| 减轻服务器压力 | 减少静态资源的请求处理量,服务器只需处理动态接口 |
| 保证更新及时生效 | 入口文件 index.html 不缓存,确保用户始终加载最新版本的 JS/CSS 引用 |
| 改善移动端体验 | 移动端网络不稳定、带宽有限,缓存可显著减少加载时间 |
不配置缓存的缺点
| 缺点 | 影响 |
|---|---|
| 每次全量下载 | 用户每次访问都要重新下载全部 JS/CSS/图片,页面加载慢 |
| 浪费带宽 | 一个 SPA 应用打包后通常几百 KB 到几 MB,重复下载浪费流量 |
| 移动端体验差 | 4G/弱网环境下,无缓存的 SPA 首次加载可能需要 5-10 秒 |
| 服务器压力大 | 所有静态资源每次都要从服务器读取和传输 |
| CDN 无法发挥效果 | 即使使用 CDN,无缓存策略也会导致频繁回源 |
配置缓存的潜在风险
| 风险 | 应对措施 |
|---|---|
| 用户看到旧版本 | 入口文件 index.html 设置不缓存,确保每次获取最新的 JS/CSS 引用 |
| 发版后不生效 | 带 hash 的资源文件名变化后自动走新文件,旧缓存不影响更新 |
| 配置复杂度高 | 使用 map 集中配置方案,降低维护成本 |
| 缓存穿透 | always 参数确保 4xx/5xx 响应也带缓存头,避免错误页面被反复请求 |
方案一:map 集中配置(当前采用)
通过 map 指令按 URI 模式匹配,自动决定缓存策略,所有 location 共用一个变量。
# http 块中集中维护
map $uri $cache_control {
default "";
~*\.html$ "no-cache, no-store, must-revalidate";
~/assets/ "public, max-age=31536000, immutable";
}
server {
# PC端
location / {
try_files $uri $uri/ /index.html;
add_header Cache-Control $cache_control always;
}
# 移动端
location /mobile {
alias /opt/project/application/front-h5;
index index.html;
try_files $uri $uri/ /mobile/index.html;
add_header Cache-Control $cache_control always;
}
}
方案二:传统分散配置
在每个 location 中单独写 add_header,需要为不同缓存策略拆分多个 location。
server {
# PC端
location / {
try_files $uri $uri/ /index.html;
}
location = /index.html {
add_header Cache-Control "no-cache, no-store, must-revalidate";
add_header Pragma "no-cache";
add_header Expires "0";
}
location /assets/ {
add_header Cache-Control "public, max-age=31536000, immutable";
}
# 移动端
location /mobile {
alias /opt/project/application/front-h5;
index index.html;
try_files $uri $uri/ /mobile/index.html;
}
location = /mobile/index.html {
alias /opt/project/application/front-h5/index.html;
add_header Cache-Control "no-cache, no-store, must-revalidate";
add_header Pragma "no-cache";
add_header Expires "0";
}
location /mobile/assets/ {
alias /opt/project/application/front-h5/assets/;
add_header Cache-Control "public, max-age=31536000, immutable";
}
}
方案三:传统简单配置(直接在主 location 加 header)
不拆分子 location,直接在主 location 中添加缓存头,所有文件统一处理。
server {
# PC端
location / {
try_files $uri $uri/ /index.html;
add_header Cache-Control "no-cache, no-store, must-revalidate";
}
# 移动端
location /mobile {
alias /opt/project/application/front-h5;
index index.html;
try_files $uri $uri/ /mobile/index.html;
add_header Cache-Control "no-cache, no-store, must-revalidate";
}
}
优缺点对比
| 对比维度 | map 集中配置 | 传统分散配置 | 传统简单配置 |
|---|---|---|---|
| location 数量 | 2 个 | 6 个 | 2 个 |
| 缓存规则维护 | 只改 map 一个地方 |
需改 4 个 location | 改 2 个 location |
| 路径维护 | alias 各写 1 次 | alias 写 3 次 | alias 写 1 次 |
| 缓存精度 | html 不缓存 + assets 长期缓存 | html 不缓存 + assets 长期缓存 | 全部不缓存 |
| 带 hash 资源缓存 | 1 年(性能最优) | 1 年(性能最优) | 不缓存(每次重新下载) |
| 页面加载速度 | 快 | 快 | 慢(JS/CSS/图片每次全量下载) |
| 流量消耗 | 低 | 低 | 高 |
| alias 继承问题 | 无 | 有(易出 404) | 无 |
| 兼容性 | nginx 1.7.5+ | 所有版本 | 所有版本 |
| 可读性 | 规则集中,一目了然 | 分散各处 | 简单直接 |
| 新增缓存规则 | map 加一行 | 新增 location 块 | 不好加,只能全部统一 |
| 适用规模 | 中大型项目 | 中大型项目 | 小型/临时项目 |
方案三的典型问题
这种方案最大的问题是所有静态资源都不缓存:
- 用户每次打开页面,浏览器都要重新下载全部 JS、CSS、图片、字体
- 一个 uni-app H5 应用打包后通常有 50-100 个静态文件,总计几百 KB 到几 MB
- 在移动网络(4G/弱网)环境下,用户体验会明显变差
- 服务器带宽浪费严重
唯一的优点是配置最简单,且不会出 alias 继承导致的 404 问题。
适用场景
推荐用 map 集中配置(方案一)
- SPA 项目(Vue/React/uni-app H5),缓存规则统一
- 多个入口(PC + 移动端)共用同一套缓存策略
- 团队多人维护,降低改错风险
- nginx 版本 ≥ 1.7.5
推荐用传统分散配置(方案二)
- 需要对某个特定路径做完全不同的缓存策略
- nginx 版本较老(< 1.7.5)
- 需要同时设置
Pragma、Expires等额外 header 兼容旧浏览器
可用传统简单配置(方案三)
- 小型或临时项目,不在意性能
- 对 nginx 配置不熟悉,不想踩 alias 继承的坑
- 静态资源很小(只有几个文件),缓存收益不明显
- 内部测试环境,不面向用户
注意事项
map 方案的注意点
add_header使用变量时,若变量为空字符串"",nginx 不会发送该 header(符合预期)always参数确保即使响应码为 4xx/5xx 也会带上 header- map 中的正则匹配按从上到下的顺序,首个匹配生效
传统方案的常见坑
- alias 不继承(方案二):子 location(如
location = /mobile/index.html)不会继承父 location 的alias,会回退到 server 级root,导致 404 - add_header 覆盖问题(方案二):子 location 中的
add_header会覆盖父 location 的所有add_header,不是追加 - 维护遗漏(方案二):新增前端入口时容易忘记同步缓存配置
- 全量下载浪费带宽(方案三):所有静态资源每次访问都重新下载,移动端用户体感明显
总结
| 方案一 (map) | 方案二 (分散) | 方案三 (简单) | |
|---|---|---|---|
| 配置复杂度 | 中 | 高 | 低 |
| 缓存精度 | 高 | 高 | 无 |
| 性能表现 | 优 | 优 | 差 |
| 维护成本 | 低 | 高 | 低 |
| 出错风险 | 低 | 高 | 低 |
| 综合评价 | 推荐 | 特殊场景 | 临时使用 |
openEuler 是由开放原子开源基金会孵化的全场景开源操作系统项目,面向数字基础设施四大核心场景(服务器、云计算、边缘计算、嵌入式),全面支持 ARM、x86、RISC-V、loongArch、PowerPC、SW-64 等多样性计算架构
更多推荐
所有评论(0)