为什么要配置缓存策略

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 方案的注意点

  1. add_header 使用变量时,若变量为空字符串 "",nginx 不会发送该 header(符合预期)
  2. always 参数确保即使响应码为 4xx/5xx 也会带上 header
  3. map 中的正则匹配按从上到下的顺序,首个匹配生效

传统方案的常见坑

  1. alias 不继承(方案二):子 location(如 location = /mobile/index.html)不会继承父 location 的 alias,会回退到 server 级 root,导致 404
  2. add_header 覆盖问题(方案二):子 location 中的 add_header 会覆盖父 location 的所有 add_header,不是追加
  3. 维护遗漏(方案二):新增前端入口时容易忘记同步缓存配置
  4. 全量下载浪费带宽(方案三):所有静态资源每次访问都重新下载,移动端用户体感明显

总结

方案一 (map)方案二 (分散)方案三 (简单)
配置复杂度中高低
缓存精度高高无
性能表现优优差
维护成本低高低
出错风险低高低
综合评价推荐特殊场景临时使用
Logo

汇聚全球AI编程工具,助力开发者即刻编程。

更多推荐