Cloudflare 加速实战:从缓存规则到 Worker 边缘优化源码指南
Cloudflare 性能优化教程|附源码
在现代网站架构中,性能优化已经不再只是“压缩几张图片”或“开启缓存”这么简单。用户访问速度、首屏加载时间、接口响应延迟、全球访问稳定性、抗突发流量能力,都会直接影响网站体验、SEO 排名以及转化率。
Cloudflare 作为全球领先的 CDN、边缘计算与安全平台,提供了非常丰富的性能优化能力,包括 CDN 缓存、Brotli 压缩、HTTP/3、图片优化、Worker 边缘函数、Cache Rules、Tiered Cache、Argo Smart Routing 等。
本文将系统介绍如何使用 Cloudflare 对网站进行性能优化,并提供可直接参考的配置方案与源码示例。
一、Cloudflare 性能优化的核心思路
在开始配置之前,我们需要先理解 Cloudflare 的优化逻辑。
Cloudflare 位于用户和源站之间:
用户浏览器
↓
Cloudflare 边缘节点
↓
源站服务器
当用户访问网站时,请求会先到达离用户最近的 Cloudflare 边缘节点。如果资源已经被 Cloudflare 缓存,则直接从边缘节点返回,不再请求源站。这样可以显著降低延迟,并减少源站压力。
Cloudflare 性能优化主要围绕以下几个方向展开:
-
减少源站请求
- 静态资源缓存
- HTML 页面缓存
- API 合理缓存
- Cache Rules 精细化控制
-
缩小传输体积
- Brotli / Gzip 压缩
- JS、CSS、HTML 压缩
- 图片 WebP / AVIF 优化
-
提升网络传输效率
- HTTP/2
- HTTP/3 QUIC
- 0-RTT
- Early Hints
-
缩短动态请求耗时
- Worker 边缘缓存
- KV / R2 边缘数据存储
- Argo Smart Routing
-
优化浏览器缓存策略
- Cache-Control
- ETag
- immutable
- stale-while-revalidate
二、基础准备:接入 Cloudflare
1. 添加站点
进入 Cloudflare 控制台,点击:
Add a site
输入你的域名,例如:
example.com
Cloudflare 会扫描现有 DNS 记录。
2. 修改域名 NS 服务器
Cloudflare 会分配两个 Nameserver,例如:
lisa.ns.cloudflare.com
tom.ns.cloudflare.com
你需要到域名注册商后台,将原有 NS 修改为 Cloudflare 提供的 NS。
等待 DNS 生效后,Cloudflare 会显示站点已激活。
3. 确认 DNS 代理状态
在 DNS 页面中,你会看到每条记录旁边有一个云朵图标:
- 橙色云朵:经过 Cloudflare 代理
- 灰色云朵:仅 DNS 解析,不走 Cloudflare
如果希望 Cloudflare 对网站进行缓存和性能优化,通常需要开启橙色云朵。
例如:
| 类型 | 名称 | 内容 | 状态 |
|---|---|---|---|
| A | @ | 1.2.3.4 | 已代理 |
| CNAME | www | example.com | 已代理 |
三、开启基础性能功能
进入 Cloudflare 控制台:
Speed > Optimization
建议开启以下功能。
1. Brotli 压缩
Brotli 是比 Gzip 压缩率更高的压缩算法,适合 HTML、CSS、JS、JSON、SVG 等文本资源。
建议开启:
Speed > Optimization > Content Optimization > Brotli
开启后,支持 Brotli 的浏览器会自动使用 Brotli 压缩资源。
浏览器请求头示例:
Accept-Encoding: gzip, deflate, br
Cloudflare 返回头示例:
Content-Encoding: br
2. Auto Minify
Auto Minify 可以自动压缩:
- JavaScript
- CSS
- HTML
建议开启:
Speed > Optimization > Auto Minify
如果你的网站已经在构建阶段使用了 Vite、Webpack、Rollup、Next.js 等工具进行压缩,那么这个功能可以不开。
一般建议:
| 网站类型 | 是否开启 Auto Minify |
|---|---|
| WordPress | 可以开启 |
| 静态博客 | 可以开启 |
| 前端工程化项目 | 可不开 |
| 复杂 SPA 应用 | 谨慎开启 |
3. HTTP/2 与 HTTP/3
Cloudflare 默认支持 HTTP/2,建议开启 HTTP/3。
路径:
Speed > Optimization > Protocol Optimization > HTTP/3
HTTP/3 基于 QUIC 协议,使用 UDP,能减少连接建立时间,尤其适合移动网络和跨国访问场景。
4. Early Hints
Early Hints 使用 HTTP 103 状态码,让浏览器在正式 HTML 返回前提前加载关键资源。
开启路径:
Speed > Optimization > Protocol Optimization > Early Hints
如果你的页面中有明确的 preload 资源,例如字体、CSS、关键 JS,Early Hints 会更有帮助。
HTML 示例:
四、配置浏览器缓存策略
Cloudflare 的缓存分为两层:
-
边缘缓存
- Cloudflare 节点是否缓存资源
- 缓存多久
-
浏览器缓存
- 用户浏览器是否缓存资源
- 缓存多久
良好的缓存策略可以大幅减少重复请求。
五、推荐的源站缓存头配置
如果你使用 Nginx,可以参考以下配置。
Nginx 静态资源缓存配置源码
server {
listen 80;
server_name example.com www.example.com;
root /var/www/example.com;
index index.html;
gzip on;
gzip_types text/plain text/css application/json application/javascript application/xml image/svg+xml;
gzip_min_length 1024;
location ~* \.(?:css|js|mjs|json|svg|ico|woff2?|ttf|eot)$ {
access_log off;
expires 1y;
add_header Cache-Control "public, max-age=31536000, immutable";
try_files $uri =404;
}
location ~* \.(?:jpg|jpeg|png|gif|webp|avif)$ {
access_log off;
expires 30d;
add_header Cache-Control "public, max-age=2592000";
try_files $uri =404;
}
location / {
try_files $uri $uri/ /index.html;
add_header Cache-Control "public, max-age=0, must-revalidate";
}
}
这个配置的核心思想是:
- 带 hash 的 JS/CSS 文件缓存一年
- 图片缓存 30 天
- HTML 不长期缓存,避免更新不及时
- 使用
immutable告诉浏览器资源不会变化
例如:
/assets/app.8f3a1c2.js
/assets/style.b91d0.css
这类文件名带 hash 的资源非常适合长期缓存。
六、使用 Cloudflare Cache Rules 精细化缓存
Cloudflare 原来的 Page Rules 已经逐渐被 Cache Rules 替代。Cache Rules 更灵活,推荐使用。
进入:
Caching > Cache Rules
1. 缓存静态资源
规则表达式:
(http.request.uri.path matches "\.(css|js|mjs|json|jpg|jpeg|png|gif|webp|avif|svg|ico|woff|woff2|ttf|eot)$")
配置建议:
Cache eligibility: Eligible for cache
Edge TTL: 1 month
Browser TTL: Respect origin
如果你的资源文件名带 hash,可以将 Edge TTL 设置为一年。
2. 缓存 HTML 页面
对于博客、文档、企业官网、内容型站点,HTML 页面通常可以缓存。
规则表达式:
(http.request.uri.path eq "/" or http.request.uri.path contains "/posts/" or http.request.uri.path contains "/docs/")
配置建议:
Cache eligibility: Eligible for cache
Edge TTL: 10 minutes
Browser TTL: 5 minutes
HTML 缓存不要设置太长,除非你有自动清理缓存机制。
3. 排除后台与登录页面
如果是 WordPress、CMS、管理系统,必须排除登录态页面,避免缓存用户隐私内容。
规则表达式示例:
(http.request.uri.path contains "/wp-admin" or http.request.uri.path contains "/wp-login.php" or http.cookie contains "wordpress_logged_in")
配置:
Cache eligibility: Bypass cache
常见需要绕过缓存的路径:
/admin
/login
/logout
/api/user
/api/auth
/cart
/checkout
/account
七、Cloudflare Worker 边缘缓存实战
Cloudflare Worker 是运行在 Cloudflare 边缘节点上的 JavaScript 函数。它可以拦截请求、修改响应、实现自定义缓存逻辑。
下面实现一个常见功能:
对 HTML 页面进行边缘缓存,缓存 60 秒,同时使用 stale-while-revalidate 思路提升访问速度。
八、Worker 项目源码
1. 项目结构
cloudflare-performance-worker/
├── package.json
├── wrangler.toml
└── src/
└── index.js
2. package.json
{
"name": "cloudflare-performance-worker",
"version": "1.0.0",
"description": "Cloudflare Worker performance optimization demo",
"main": "src/index.js",
"scripts": {
"dev": "wrangler dev",
"deploy": "wrangler deploy"
},
"devDependencies": {
"wrangler": "^3.0.0"
}
}
3. wrangler.toml
name = "cloudflare-performance-worker"
main = "src/index.js"
compatibility_date = "2024-06-01"
routes = [
{ pattern = "example.com/*", zone_name = "example.com" },
{ pattern = "www.example.com/*", zone_name = "example.com" }
]
部署前请将 example.com 修改为你的真实域名。
4. src/index.js
export default {
async fetch(request, env, ctx) {
const url = new URL(request.url);
// 只处理 GET / HEAD 请求
if (!["GET", "HEAD"].includes(request.method)) {
return fetch(request);
}
// 后台、登录、接口、支付等路径不缓存
const bypassPaths = [
"/admin",
"/login",
"/logout",
"/api",
"/cart",
"/checkout",
"/account"
];
if (bypassPaths.some(path => url.pathname.startsWith(path))) {
return fetch(request, {
cf: {
cacheTtl: 0,
cacheEverything: false
}
});
}
// 如果带有登录态 Cookie,则不缓存
const cookie = request.headers.get("Cookie") || "";
const authCookieKeywords = [
"session",
"token",
"auth",
"wordpress_logged_in"
];
if (authCookieKeywords.some(key => cookie.includes(key))) {
return fetch(request);
}
// 静态资源交给 Cloudflare 默认缓存策略
if (isStaticAsset(url.pathname)) {
return fetch(request);
}
// 构造缓存 Key
const cacheKey = new Request(url.toString(), request);
const cache = caches.default;
// 尝试读取边缘缓存
let response = await cache.match(cacheKey);
if (response) {
response = new Response(response.body, response);
response.headers.set("X-Worker-Cache", "HIT");
return response;
}
// 回源请求
response = await fetch(request, {
cf: {
cacheEverything: true,
cacheTtl: 60
}
});
// 只缓存成功的 HTML 响应
const contentType = response.headers.get("Content-Type") || "";
if (
response.status === 200 &&
contentType.includes("text/html")
) {
const cachedResponse = new Response(response.body, response);
cachedResponse.headers.set(
"Cache-Control",
"public, max-age=60, stale-while-revalidate=300"
);
cachedResponse.headers.set("X-Worker-Cache", "MISS");
ctx.waitUntil(cache.put(cacheKey, cachedResponse.clone()));
return cachedResponse;
}
return response;
}
};
function isStaticAsset(pathname) {
return /\.(css|js|mjs|json|jpg|jpeg|png|gif|webp|avif|svg|ico|woff|woff2|ttf|eot)$/i.test(pathname);
}
九、Worker 部署步骤
1. 安装 Wrangler
npm install -g wrangler
或者在项目中安装:
npm install
2. 登录 Cloudflare
wrangler login
浏览器会打开 Cloudflare 授权页面,确认即可。
3. 本地调试
npm run dev
4. 部署 Worker
npm run deploy
部署成功后,你可以使用 curl 检查缓存状态。
curl -I https://example.com/
返回示例:
HTTP/2 200
content-type: text/html; charset=utf-8
cache-control: public, max-age=60, stale-while-revalidate=300
x-worker-cache: HIT
cf-cache-status: HIT
十、优化图片:WebP、AVIF 与懒加载
图片通常是网页体积最大的部分。Cloudflare 提供了 Polish、Mirage、Image Resizing 等功能,不过部分功能需要付费套餐。
如果你不使用付费功能,也可以在源站完成图片优化。
1. 推荐图片格式
| 类型 | 推荐格式 |
|---|---|
| 普通照片 | WebP / AVIF |
| 透明图 | WebP / PNG |
| 图标 | SVG |
| 动图 | WebP / MP4 |
2. HTML 图片懒加载示例

注意:
- 首屏关键图片不要懒加载
- 非首屏图片建议使用
loading="lazy" - 一定要设置
width和height,减少 CLS 布局偏移
3. 响应式图片源码
浏览器会优先选择 AVIF,其次 WebP,最后 JPG。
十一、优化字体加载
字体文件也会影响首屏渲染。建议:
- 字体使用 WOFF2
- 只加载必要字重
- 使用
font-display: swap - 对关键字体 preload
示例:
CSS:
@font-face {
font-family: "Inter";
src: url("/fonts/inter-var.woff2") format("woff2");
font-weight: 100 900;
font-display: swap;
}
body {
font-family: "Inter", system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
}
对于中文网站,不建议一次性加载完整中文字体,因为体积往往非常大。更推荐使用系统字体:
body {
font-family:
-apple-system,
BlinkMacSystemFont,
"Segoe UI",
"PingFang SC",
"Hiragino Sans GB",
"Microsoft YaHei",
sans-serif;
}
十二、为 API 设置合理缓存
并不是所有 API 都不能缓存。对于公共数据接口,例如文章列表、分类列表、站点配置,可以设置短时间缓存。
API 响应头示例
Cache-Control: public, max-age=30, stale-while-revalidate=120
表示:
- 浏览器和 CDN 可缓存 30 秒
- 过期后 120 秒内可以先返回旧内容,同时后台更新
Node.js Express 示例源码
import express from "express";
const app = express();
app.get("/api/posts", async (req, res) => {
const posts = [
{
id: 1,
title: "Cloudflare 性能优化教程",
slug: "cloudflare-performance-guide"
},
{
id: 2,
title: "CDN 缓存最佳实践",
slug: "cdn-cache-best-practices"
}
];
res.setHeader(
"Cache-Control",
"public, max-age=30, stale-while-revalidate=120"
);
res.json({
code: 0,
data: posts
});
});
app.get("/api/user", async (req, res) => {
// 用户私有数据,必须禁止公共缓存
res.setHeader("Cache-Control", "private, no-store");
res.json({
code: 0,
data: {
username: "demo"
}
});
});
app.listen(3000, () => {
console.log("Server running at http://localhost:3000");
});
十三、Cloudflare 缓存清理策略
缓存不是越久越好,关键是要可控。
常见清理方式:
- 手动 Purge Everything
- 按 URL 清理
- 按 Cache-Tag 清理
- 发布系统自动清理
如果是生产环境,不建议频繁使用 Purge Everything,因为这会导致所有边缘节点缓存失效,短时间内源站压力增大。
十四、使用 API 自动清理缓存源码
1. Bash 脚本
#!/usr/bin/env bash
CF_API_TOKEN="你的 Cloudflare API Token"
CF_ZONE_ID="你的 Zone ID"
curl -X POST "https://api.cloudflare.com/client/v4/zones/${CF_ZONE_ID}/purge_cache" \
-H "Authorization: Bearer ${CF_API_TOKEN}" \
-H "Content-Type: application/json" \
--data '{
"files": [
"https://example.com/",
"https://example.com/posts/cloudflare-performance-guide"
]
}'
2. 清理全部缓存
curl -X POST "https://api.cloudflare.com/client/v4/zones/${CF_ZONE_ID}/purge_cache" \
-H "Authorization: Bearer ${CF_API_TOKEN}" \
-H "Content-Type: application/json" \
--data '{
"purge_everything": true
}'
3. Node.js 清理缓存源码
async function purgeCloudflareCache({ zoneId, apiToken, files }) {
const response = await fetch(
`https://api.cloudflare.com/client/v4/zones/${zoneId}/purge_cache`,
{
method: "POST",
headers: {
"Authorization": `Bearer ${apiToken}`,
"Content-Type": "application/json"
},
body: JSON.stringify({
files
})
}
);
const result = await response.json();
if (!result.success) {
throw new Error(`Cloudflare purge failed: ${JSON.stringify(result.errors)}`);
}
return result;
}
purgeCloudflareCache({
zoneId: process.env.CF_ZONE_ID,
apiToken: process.env.CF_API_TOKEN,
files: [
"https://example.com/",
"https://example.com/posts/cloudflare-performance-guide"
]
}).then(console.log).catch(console.error);
十五、开启 Tiered Cache
Tiered Cache 是 Cloudflare 的分层缓存功能。
普通 CDN 缓存模式下,如果多个边缘节点都没有缓存,就会分别回源。而 Tiered Cache 会让下层边缘节点先请求上层缓存节点,只有上层节点也没有缓存时才回源。
效果:
用户
↓
本地边缘节点
↓
上层缓存节点
↓
源站
开启路径:
Caching > Tiered Cache
建议开启:
Tiered Cache: On
对于全球访问的网站,Tiered Cache 可以明显降低源站请求次数。
十六、是否需要开启 Argo Smart Routing?
Argo Smart Routing 是 Cloudflare 的智能路由功能,属于付费功能。它会根据实时网络状况选择更快的路径访问源站。
适合以下场景:
- 海外用户访问国内源站
- 国内用户访问海外源站
- 全球用户访问单一源站
- 动态请求较多
- 对延迟比较敏感
如果你的网站大部分内容已经被 Cloudflare 缓存,Argo 的收益可能有限;如果动态接口较多,Argo 的收益会更明显。
十七、Cloudflare Workers KV 缓存配置示例
如果你的页面或接口数据不是实时变化,可以将部分数据放入 Workers KV,实现边缘读取。
Worker KV 示例源码
export default {
async fetch(request, env) {
const url = new URL(request.url);
if (url.pathname === "/api/site-config") {
const cached = await env.SITE_CONFIG.get("config", {
type: "json"
});
if (cached) {
return Response.json(cached, {
headers: {
"Cache-Control": "public, max-age=60",
"X-KV-Cache": "HIT"
}
});
}
const config = {
siteName: "Example",
description: "Cloudflare performance demo",
theme: "light"
};
await env.SITE_CONFIG.put("config", JSON.stringify(config), {
expirationTtl: 300
});
return Response.json(config, {
headers: {
"Cache-Control": "public, max-age=60",
"X-KV-Cache": "MISS"
}
});
}
return fetch(request);
}
};
对应的 wrangler.toml:
name = "kv-cache-demo"
main = "src/index.js"
compatibility_date = "2024-06-01"
kv_namespaces = [
{ binding = "SITE_CONFIG", id = "你的 KV Namespace ID" }
]
KV 适合缓存:
- 站点配置
- 公共文章数据
- 导航菜单
- 地区配置
- 低频更新的 JSON 数据
不适合:
- 强一致性交易数据
- 用户私密信息
- 高频写入数据
十八、安全与性能的平衡
很多人开启 Cloudflare 后,只关注速度,而忽略安全配置。实际上,安全规则如果配置不当,也可能影响性能。
建议:
- 不要对所有请求都启用高强度 Challenge
- 对静态资源不要启用复杂 WAF 检查
- 对 API 做限流,而不是一刀切阻断
- 后台路径单独设置访问规则
- 开启 Bot Fight Mode 前要观察误伤情况
例如可以给后台路径设置更严格规则:
(http.request.uri.path contains "/admin")
操作:
Managed Challenge
而静态资源路径:
/assets/*
/images/*
/fonts/*
则尽量避免复杂验证,否则会影响加载速度。
十九、性能测试方法
优化完成后,需要用数据验证效果。
推荐工具:
- Google PageSpeed Insights
- Lighthouse
- WebPageTest
- GTmetrix
- Chrome DevTools Network
- curl
- Cloudflare Analytics
curl 检查缓存
curl -I https://example.com/assets/app.js
重点关注:
cf-cache-status: HIT
cache-control: public, max-age=31536000, immutable
content-encoding: br
server: cloudflare
常见 cf-cache-status 含义:
| 状态 | 含义 |
|---|---|
| HIT | 命中 Cloudflare 缓存 |
| MISS | 未命中,已回源 |
| BYPASS | 绕过缓存 |
| DYNAMIC | 动态内容未缓存 |
| EXPIRED | 缓存过期,重新回源 |
| REVALIDATED | 已重新验证 |
| STALE | 返回旧缓存 |
二十、推荐最终配置清单
下面是一套适合大多数中文内容站、博客、企业官网的 Cloudflare 配置:
| 配置项 | 推荐值 |
|---|---|
| SSL/TLS | Full strict |
| Brotli | 开启 |
| HTTP/2 | 开启 |
| HTTP/3 | 开启 |
| Early Hints | 开启 |
| Auto Minify | 视情况开启 |
| Tiered Cache | 开启 |
| 静态资源 Edge TTL | 1 个月至 1 年 |
| HTML Edge TTL | 1 分钟至 10 分钟 |
| API 公共数据缓存 | 10 秒至 60 秒 |
| 登录/后台/支付页面 | Bypass |
| 图片格式 | AVIF / WebP |
| 字体格式 | WOFF2 |
| Argo | 动态请求多时考虑开启 |
二十一、常见问题排查
1. 为什么 cf-cache-status 是 DYNAMIC?
通常原因是:
- Cloudflare 默认不缓存 HTML
- 源站返回了
Cache-Control: no-store - 请求带 Cookie
- 使用了 Authorization 请求头
- 没有配置 Cache Rules
- Worker 主动绕过缓存
解决方案:
- 为 HTML 配置 Cache Rules
- 检查源站响应头
- 排除不必要 Cookie
- 使用 Worker 自定义缓存逻辑
2. 为什么开启缓存后页面内容不更新?
原因通常是缓存时间太长,或者发布后没有清理缓存。
解决方案:
- HTML Edge TTL 不要太长
- 静态资源使用文件名 hash
- 发布时调用 Cloudflare API 清理相关 URL
- 对 CMS 后台页面强制 Bypass
3. 为什么登录后页面显示异常?
可能是登录态页面被缓存了。
必须绕过:
/admin
/login
/account
/cart
/checkout
同时要根据 Cookie 判断登录状态,登录用户不走公共缓存。
4. 为什么图片没有变成 WebP?
可能原因:
- 未开启 Cloudflare Polish
- 套餐不支持
- 图片本身格式不适合转换
- 浏览器请求头不支持 WebP
- 源站已经返回不可转换格式
如果不使用 Polish,建议构建阶段生成 WebP / AVIF。
二十二、生产环境优化建议
最后给出一套更稳妥的生产实践:
-
先优化静态资源,再优化 HTML
- 静态资源缓存风险低
- HTML 缓存容易影响更新和登录态
-
所有静态资源文件名必须带 hash
- 例如
app.a8c9e2.js - 避免用户拿到旧版本文件
- 例如
-
缓存规则先小范围测试
- 可以先对
/docs/*、/blog/*生效 - 确认无误后再扩大范围
- 可以先对
-
后台和用户相关路径必须 Bypass
- 登录态页面不能公共缓存
-
发布系统集成缓存清理
- 发布文章后清理文章页、首页、分类页
- 不要频繁全站清理
-
持续观察 Analytics
- 查看缓存命中率
- 查看源站请求量
- 查看错误率和响应时间
总结
Cloudflare 性能优化并不是简单地“打开 CDN”就结束了,而是需要结合网站类型、资源结构、更新频率和用户访问区域进行系统配置。
对于大多数网站,最值得优先完成的是:
- 开启 Brotli、HTTP/3、Early Hints
- 配置合理的源站
Cache-Control - 使用 Cache Rules 缓存静态资源
- 对博客、文档类 HTML 页面设置短时间边缘缓存
- 排除登录、后台、支付、用户中心等动态页面
- 使用 Worker 实现更灵活的边缘缓存
- 发布时自动调用 API 清理缓存
如果配置得当,Cloudflare 可以显著提升网站访问速度,降低源站压力,并增强全球访问稳定性。对于内容型网站、企业官网、静态站点、博客系统而言,缓存命中率达到 80% 以上并不困难;对于动态业务系统,也可以通过 API 分级缓存、Worker 和 KV 等方式获得明显收益。