惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
G
Google Developers Blog
Hugging Face - Blog
Hugging Face - Blog
博客园 - 【当耐特】
S
SegmentFault 最新的问题
宝玉的分享
宝玉的分享
博客园 - Franky
博客园_首页
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
WordPress大学
WordPress大学
有赞技术团队
有赞技术团队
月光博客
月光博客
博客园 - 聂微东
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
小众软件
小众软件
Microsoft Security Blog
Microsoft Security Blog
Last Week in AI
Last Week in AI
Vercel News
Vercel News
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
爱范儿
爱范儿
J
Java Code Geeks
博客园 - 叶小钗
Engineering at Meta
Engineering at Meta
阮一峰的网络日志
阮一峰的网络日志

Netlify Developers

AI model comparison using Netlify's AI Gateway | Netlify Developers Build an AI agent to automatically process and summarize form submissions | Netlify Developers Build an AI agent to automatically generate relevant images for blog posts | Netlify Developers Prerendering SPA content pages to enable AI agent access | Netlify Developers Identify image optimization opportunities with Netlify Observability | Netlify Developers Fix top 404 page not found errors with Netlify Observability | Netlify Developers Introducing AI Gateway: built-in AI model access on Netlify | Netlify Developers Introducing Observability: your project insights on Netlify | Netlify Developers From first publish to first update with AI agents | Netlify Developers How to use Agent Runners on Netlify | Netlify Developers Add forms to your project with AI + Netlify | Netlify Developers Track Real User Metrics | Netlify Developers Lighthouse performance scores on Netlify | Netlify Developers Review your AI project before you ship | Netlify Developers Using environment variables in AI Projects on Netlify | Netlify Developers Build prototypes and MVPs fast with AI + Netlify | Netlify Developers Pause auto-publishing on Netlify | Netlify Developers Run serverless functions, storage, and more natively in Nuxt dev | Netlify Developers Netlify Office Hours: The AX Arcade challenge | Netlify Developers Netlify Office Hours: Prompting with style | Netlify Developers Netlify Office Hours: RAG Apps with OpenAI + Netlify DB | Netlify Developers How to build a RAG application with Neon, Netlify & OpenAI | Netlify Developers Netlify Office Hours: Netlify DB (powered by Neon) | Netlify Developers Netlify Office Hours: Netlify MCP Server | Netlify Developers Netlify Office Hours: Netlify Vite Plugin | Netlify Developers Building MCPs with Netlify | Netlify Developers Deploying sites from your AI tool | Netlify Developers Adding your domain using Netlify API | Netlify Developers Build a context driven chat bot with Netlify Blob and OpenAI | Netlify Developers Simplify deployments with Netlify’s branch-matching environment variables | Netlify Developers
Advanced caching made easy | Netlify Developers
2024-06-20 · via Netlify Developers

Netlify’s global network supports a powerful range of cache features, most of which can be controlled via response headers. Now you don’t need to remember the different header names, directives and best practices to serve dynamic content that is fast and fresh.

#TL;DR

The cdn-cache-control package has a simple API and sensible defaults that makes it easy to generate the headers needed for common caching tasks. It works anywhere that lets you set response headers, including Netlify Functions and Edge Functions, as well as natively within most web frameworks.

Netlify supports several advanced cache directives that can be controlled via response headers. This is particularly useful for server-side rendering of web content, as it allows you to manually handle the invalidation of content, ensuring it stays fast and fresh. You can either set the cached responses to expire after a certain period, or purge it manually using the API. Using stale-while-revalidate allows you to update content in the background without blocking requests.

The full caching docs show how to have full control over your cache headers. You can use standard Cache-Control and CDN-Cache-Control headers, or target the cache more specifically with the Netlify-CDN-Cache-Control header. You can also use the Netlify-Cache-Tag header to invalidate cached content. On-demand invalidation allows you to purge content from the cache individually or in bulk. Because this is based on standard HTTP headers, it works with any web framework or function. You can see detailed guides for Remix and Astro in the Netlify developer hub.

#Using the cdn-cache-control package

While manually setting headers gives you powerful, fine-grained control over the cache it can be hard to remember the correct headers to set, and the best practices for different types of content. I created the cdn-cache-control package to make it easy to generate the correct headers for common use cases. It extends the Fetch standard Headers class, adding a simple, chainable API with sensible defaults for common use cases. It works by setting the Cache-Control and Netlify-CDN-Cache-Control headers to the appropriate values. It also has helpers for setting the Netlify-Cache-Tag header, which is used to invalidate cached content.

#Installing the package

The package can be installed from npm:

npm install cdn-cache-control

#Using the package

The module exports a single class, CacheHeaders, which is a subclass of the fetch Headers class. By default it sets the Cache-Control and Netlify-CDN-Cache-Control headers to sensible values for content that should be cached by the CDN and revalidated by the browser. It also provides a chainable API for setting cache headers.

Like a regular Headers object it can optionally be created with a value to pre-populate the header values. This can be an existing Headers object, a plain object or array with existing header values. In that case it will default to using existing s-maxage directives if present.

This example shows simple usage of the package:

import { CacheHeaders } from "cdn-cache-control";

import type { Config } from "@netlify/functions";

export default async function handler(request: Request): Promise<Response> {

const headers = new CacheHeaders();

return new Response("Hello, world!", { headers });

}

export const config: Config {

path: "/hello"

}

This sets the Netlify-CDN-Cache-Control header to public,s-maxage=31536000,durable,must-revalidate, which tells the CDN to cache the content for a year and use Netlify’s Durable Cache for improved performance. It sets Cache-Control to public,max-age=0,must-revalidate, which tells the browser to always check with the CDN for a fresh version. You should combine this with an ETag or Last-Modified header to allow the CDN to serve a 304 Not Modified response when the content hasn’t changed.

#Tagging content for invalidation

If you need to purge cached content you can add cache tags to your responses. This is particularly useful if your responses are based on an API that may change. You can use a webhook to purge the cache when content changes. For a complete example see the Astro guide, but read on for a simple guide.

In this example we add a cache tag to the response based on the id of the data:

import type { Config, Context } from "@netlify/functions";

import { CacheHeaders } from "cdn-cache-control";

import etag from "etag";

import { getPet } from "./pets-api.js";

export default async function handler(request: Request, context: Context): Promise<Response> {

const pet = await getPet(context.params.slug);

if(!pet) {

return new Response("Not found", { status: 404 });

}

// Create the cache headers, setting the ETag to the hash of the pet object

const headers = new CacheHeaders({

"etag": etag(JSON.stringify(pet)),

// Use the chained 'tag' method to add a cache tag

}).tag("pets", "pet-" + pet.id);

return Response.json(pet, { headers });

}

export const config: Config {

path: "/pets/:slug"

}

#Expiring content

By default the CacheHeaders class will cache your content for up to a year, or until you next deploy. If you want to set a different expiry time you can use the ttl (time to live) method. You can pass a number of seconds to the ttl method to set a different value. There are helper constants for common values:

import { CacheHeaders, ONE_WEEK } from "cdn-cache-control";

// Cache content for up to a week

const headers = new CacheHeaders().ttl(ONE_WEEK);

#Faster loading with stale-while-revalidate

Enabling the stale-while-revalidate directive tells the CDN to return stale content after it has expired, but then regenerate the content in the background. This is good for pages that may be slow to render, but where it’s ok to return stale content for a while. You can enable stale-while-revalidate with the swr method:

import { CacheHeaders } from "cdn-cache-control";

const headers = new CacheHeaders().swr();

By default it will return stale content for up to a week, but you can pass a number of seconds to the swr method to set a different value.

import { CacheHeaders, ONE_DAY } from "cdn-cache-control";

// Return stale content for up to an hour, and revalidate it in the background

const headers = new CacheHeaders().swr(ONE_HOUR);

By default, calling swr will expire content immediately and regenerate it after each request. If you’re happy to keep the content fresh for a while you can use the ttl method alongside swr.

import { CacheHeaders, ONE_HOUR } from "cdn-cache-control";

// Content is fresh for 30 seconds, then return stale content for up to an hour

const headers = new CacheHeaders().ttl(30).swr(ONE_HOUR);

#Immutable content

Sometimes you are generating content that you know will never change. This might be an asset that includes a hash in the URL, or other unchanging unique content. For these you can use the immutable to cache the content for the year in both the CDN and the browser, adding the immutable directive to the headers.

import { CacheHeaders } from "cdn-cache-control";

// Cache content for up to a year, and tell the browser it will never change

const headers = new CacheHeaders().immutable();

Careful

Be careful when using immutable as it will cache the content for a year in the browser. If you need to change the content you will need to change the URL or the content itself. It is best to restrict its use to cases where the URL is guaranteed to be unique and unchanging, such as assets with a hash in the URL.

The CacheHeaders object works perfectly with frameworks SSR functions. It can be used anywhere you can set response headers. It is a valid fetch Headers object, so can be used with the Response constructor. Some frameworks use a readonly Headers object, where you need to set the headers in the response object directly. In this case you can use the copyTo method to copy the headers to the response object:

---

import { CacheHeaders, ONE_HOUR } from "cdn-cache-control";

new CacheHeaders().swr(ONE_HOUR).copyTo(Astro.response.headers);

---

#Troubleshooting

If you’re having trouble, the Cache-Status header can be useful for debugging. It shows the status of the cache for the request, including whether the content was served from the cache or not, and whether it was stale or fresh. For more details see the cache debugging docs.

#Learn more

For more details and full API docs, see cdn-cache-control on GitHub.