Nginx 如何配置静态资源缓存策略提升加载速度?

文章导读
对于大多数 Web 场景,最推荐的做法是在 Nginx 配置中针对 CSS、JS、图片等静态文件设置较长的过期时间,并配合文件名哈希版本控制,这样既能充分利用浏览器缓存,又能确保更新及时生效。
📋 目录
  1. 核心配置示例
  2. 缓存原理简述
  3. 配置实施步骤
  4. 验证缓存生效方法
  5. 常见问题与风险
  6. 参考来源
A A

对于大多数 Web 场景,最推荐的做法是在 Nginx 配置中针对 CSS、JS、图片等静态文件设置较长的过期时间,并配合文件名哈希版本控制,这样既能充分利用浏览器缓存,又能确保更新及时生效。

先说结论:配置静态资源缓存的核心是平衡“缓存命中率”与“内容更新及时性”,盲目延长缓存时间而不做版本管理会导致用户无法获取最新文件。

  • 先定位:区分动态 HTML 与静态资源,避免对首页或 html 文件设置强缓存
  • 先做:使用 expires 指令设置缓存时长,配合 add_header 补充控制
  • 再验证:通过 curl 或浏览器开发者工具检查响应头是否包含 Cache-Control

核心配置示例

以下是一个完整的 server 块配置示例,展示了静态资源缓存 location 应放置的位置,以及如何保留安全头:

server {
    listen 80;
    server_name example.com;
    root /var/www/html;

    # 全局安全头(若在 location 中定义 add_header,此处可能失效)
    add_header X-Frame-Options "SAMEORIGIN" always;
    add_header X-Content-Type-Options "nosniff" always;

    # 动态内容(HTML)不建议强缓存
    location / {
        try_files $uri $uri/ =404;
        add_header Cache-Control "no-cache" always;
        # 重复必要的安全头以防被覆盖
        add_header X-Frame-Options "SAMEORIGIN" always;
        add_header X-Content-Type-Options "nosniff" always;
    }

    # 静态资源缓存配置
    location ~* \.(css|js|png|jpg|jpeg|gif|ico|svg|woff|woff2)$ {
        expires 30d;
        add_header Cache-Control "public, immutable" always;
        # 重要:若 server 块有安全头,此处需重复定义或使用 include
        add_header X-Frame-Options "SAMEORIGIN" always;
        add_header X-Content-Type-Options "nosniff" always;
    }
}

缓存原理简述

浏览器默认每次请求都会向服务器询问资源是否更新。配置缓存后,服务器通过响应头告诉浏览器“这个文件 30 天内不会变”,浏览器在此期间直接使用本地副本,不再发起网络请求。这减少了服务器带宽消耗,也缩短了用户等待时间。但如果没有版本控制,文件内容变了而文件名没变,浏览器仍会使用旧缓存。

配置实施步骤

1. 备份配置:在修改前执行 cp nginx.conf nginx.conf.bak,确保出错可回滚。

2. 编辑配置:找到 server 块,添加 location 匹配静态后缀,使用正则匹配文件扩展名。注意避免匹配到 .html 或动态接口路径。

3. 设置 expires:参考官方文档,expires 可设置具体时间(如 30d)或 max,前者更常用。

4. 版本控制:构建时将文件名改为 app.abc123.css 形式,确保内容变更时 URL 也变更。

5. 重载:执行 nginx -t 检查语法,无误后执行 nginx -s reload 生效。

Nginx 如何配置静态资源缓存策略提升加载速度?

验证缓存生效方法

1. 使用命令 curl -I https://你的域名.com/style.css(请替换为实际域名)查看响应头。

2. 确认返回头中包含 Cache-Control 和 Expires 字段,且时间符合预期。

3. 在浏览器 F12 Network 面板刷新页面,观察静态资源的 Size 列是否显示 disk cache 或 memory cache。

常见问题与风险

1. add_header 继承问题:若在 location 块中定义了 add_header,Nginx 默认会清除 server 块中定义的 add_header,导致 CSP、HSTS 等安全头丢失。解决方案:在 location 块中显式重复定义必要的安全头,或使用 include 指令统一管理头部配置。

2. HTML 文件缓存:index.html 通常不建议设置长缓存,否则发布新版本后用户看不到更新,建议设置 no-cache 或较短过期时间。

3. 动态请求误缓存:确保 location 正则表达式仅匹配静态后缀,避免误匹配 .html 或动态接口路径,防止动态内容被错误缓存。

4. 304 协商:即使设置了 expires,某些情况下浏览器仍会发送 If-Modified-Since,服务器返回 304 也是正常的缓存机制。

参考来源

1. Nginx 官方文档,ngx_http_headers_module,http://nginx.org/en/docs/http/ngx_http_headers_module.html#expires