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 预览环境)