netlify-caching

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Caching on Netlify

Netlify 缓存配置

Default Behavior

默认行为

Static assets are cached automatically:
  • CDN: cached for 1 year, invalidated on every deploy
  • Browser: always revalidates (
    max-age=0, must-revalidate
    )
  • No configuration needed
Dynamic responses (functions, edge functions, proxied) are not cached by default. Add cache headers explicitly.
静态资源会被自动缓存:
  • CDN:缓存1年,每次部署时失效
  • 浏览器:始终重新验证(
    max-age=0, must-revalidate
    )
  • 无需配置
动态响应(函数、边缘函数、代理请求)默认不缓存。需显式添加缓存头。

Cache-Control Headers

Cache-Control 头信息

Three headers control caching, from most to least specific:
HeaderWho sees itUse case
Netlify-CDN-Cache-Control
Netlify CDN only (stripped before browser)CDN-only caching
CDN-Cache-Control
All CDN caches (stripped before browser)Multi-CDN setups
Cache-Control
Browser and all cachesGeneral caching
三个头信息用于控制缓存,优先级从高到低:
头信息可见对象使用场景
Netlify-CDN-Cache-Control
仅Netlify CDN(返回浏览器前会被移除)仅CDN端缓存
CDN-Cache-Control
所有CDN缓存(返回浏览器前会被移除)多CDN部署场景
Cache-Control
浏览器及所有缓存通用缓存配置

Common Patterns

常见配置模式

typescript
// Cache at CDN for 1 hour, browser always revalidates
return new Response(body, {
  headers: {
    "Netlify-CDN-Cache-Control": "public, s-maxage=3600, must-revalidate",
    "Cache-Control": "public, max-age=0, must-revalidate",
  },
});

// Stale-while-revalidate (serve stale for 2 min while refreshing)
return new Response(body, {
  headers: {
    "Netlify-CDN-Cache-Control": "public, max-age=60, stale-while-revalidate=120",
  },
});

// Durable cache (shared across edge nodes, serverless functions only)
return new Response(body, {
  headers: {
    "Netlify-CDN-Cache-Control": "public, durable, max-age=60, stale-while-revalidate=120",
  },
});
typescript
// CDN端缓存1小时,浏览器始终重新验证
return new Response(body, {
  headers: {
    "Netlify-CDN-Cache-Control": "public, s-maxage=3600, must-revalidate",
    "Cache-Control": "public, max-age=0, must-revalidate",
  },
});

// Stale-while-revalidate(返回过期内容的同时刷新缓存,最长2分钟)
return new Response(body, {
  headers: {
    "Netlify-CDN-Cache-Control": "public, max-age=60, stale-while-revalidate=120",
  },
});

// 持久缓存(跨边缘节点共享,仅适用于无服务器函数)
return new Response(body, {
  headers: {
    "Netlify-CDN-Cache-Control": "public, durable, max-age=60, stale-while-revalidate=120",
  },
});

Immutable Assets

不可变资源

For fingerprinted files (hash in filename):
toml
undefined
针对带有指纹的文件(文件名包含哈希值):
toml
undefined

netlify.toml

netlify.toml

[[headers]] for = "/assets/*" [headers.values] Cache-Control = "public, max-age=31536000, immutable"
undefined
[[headers]] for = "/assets/*" [headers.values] Cache-Control = "public, max-age=31536000, immutable"
undefined

Cache Tags and On-Demand Purge

缓存标签与按需清除

Tag responses for selective cache invalidation:
typescript
return new Response(body, {
  headers: {
    "Netlify-Cache-ID": "product,listing",
    "Netlify-CDN-Cache-Control": "public, s-maxage=86400",
  },
});
Purge by tag:
typescript
import { purgeCache } from "@netlify/functions";

export default async () => {
  await purgeCache({ tags: ["product"] });
  return new Response("Purged", { status: 202 });
};
Purge entire site:
typescript
await purgeCache();
Responses with
Netlify-Cache-ID
are excluded from automatic deploy-based invalidation — they must be purged explicitly.
为响应添加标签以实现选择性缓存失效:
typescript
return new Response(body, {
  headers: {
    "Netlify-Cache-ID": "product,listing",
    "Netlify-CDN-Cache-Control": "public, s-maxage=86400",
  },
});
按标签清除缓存:
typescript
import { purgeCache } from "@netlify/functions";

export default async () => {
  await purgeCache({ tags: ["product"] });
  return new Response("已清除缓存", { status: 202 });
};
清除全站缓存:
typescript
await purgeCache();
带有
Netlify-Cache-ID
的响应不会随部署自动失效——必须显式清除。

Cache Key Variation

缓存键自定义

Customize what creates separate cache entries:
typescript
return new Response(body, {
  headers: {
    "Netlify-Vary": "cookie=ab_test|is_logged_in",
    // Other options: query=param1|param2, header=X-Custom, country=us|de, language=en|fr
  },
});
自定义生成独立缓存条目依据:
typescript
return new Response(body, {
  headers: {
    "Netlify-Vary": "cookie=ab_test|is_logged_in",
    // 其他选项:query=param1|param2, header=X-Custom, country=us|de, language=en|fr
  },
});

Framework-Specific Caching

框架特定缓存配置

Next.js

Next.js

ISR uses Netlify's durable cache automatically (runtime 5.5.0+).
revalidatePath
and
revalidateTag
trigger cache purge.
ISR会自动使用Netlify的持久缓存(运行时版本5.5.0+)。
revalidatePath
和
revalidateTag
会触发缓存清除。

Astro / Remix

Astro / Remix

Full control over cache headers in server routes. Set
Netlify-CDN-Cache-Control
in responses for CDN caching.
在服务器路由中完全控制缓存头。在响应中设置
Netlify-CDN-Cache-Control
以启用CDN缓存。

Nuxt

Nuxt

Default Nitro preset handles caching. ISR-style patterns use
routeRules
with
swr
or
isr
options.
默认Nitro预设处理缓存。类ISR模式通过
routeRules
配置
swr
或
isr
选项实现。

Vite SPA

Vite SPA

Static assets are cached by default. API responses from Netlify Functions need explicit cache headers.
静态资源默认被缓存。来自Netlify Functions的API响应需显式设置缓存头。

Debugging

调试

Check the
Cache-Status
response header:
  • HIT
    — served from cache
  • MISS
    — generated fresh
  • REVALIDATED
    — stale content was revalidated
检查
Cache-Status
响应头:
  • HIT
    —— 从缓存返回
  • MISS
    —— 重新生成内容
  • REVALIDATED
    —— 返回过期内容并已重新验证

Constraints

限制条件

  • Basic auth disables caching for the entire site
  • Durable cache is serverless functions only (not edge functions)
  • Same URL must return identical
    Netlify-Vary
    headers across responses
  • Deploy invalidation is scoped to deploy context (production vs preview)
  • 基础认证会禁用全站缓存
  • 持久缓存仅适用于无服务器函数(不适用于边缘函数)
  • 同一URL的所有响应必须返回相同的
    Netlify-Vary
    头
  • 部署失效范围限定在部署环境(生产环境 vs 预览环境)