上一篇 下一篇 分享链接 返回 返回顶部

Cloudflare 加速实战:从缓存规则到 Worker 边缘优化源码指南

发布人:慈云数据-客服中心 发布时间:1 天前 阅读量:4

Cloudflare 性能优化教程|附源码

在现代网站架构中,性能优化已经不再只是“压缩几张图片”或“开启缓存”这么简单。用户访问速度、首屏加载时间、接口响应延迟、全球访问稳定性、抗突发流量能力,都会直接影响网站体验、SEO 排名以及转化率。

Cloudflare 作为全球领先的 CDN、边缘计算与安全平台,提供了非常丰富的性能优化能力,包括 CDN 缓存、Brotli 压缩、HTTP/3、图片优化、Worker 边缘函数、Cache Rules、Tiered Cache、Argo Smart Routing 等。

本文将系统介绍如何使用 Cloudflare 对网站进行性能优化,并提供可直接参考的配置方案与源码示例。


一、Cloudflare 性能优化的核心思路

在开始配置之前,我们需要先理解 Cloudflare 的优化逻辑。

Cloudflare 位于用户和源站之间:

用户浏览器
   ↓
Cloudflare 边缘节点
   ↓
源站服务器

当用户访问网站时,请求会先到达离用户最近的 Cloudflare 边缘节点。如果资源已经被 Cloudflare 缓存,则直接从边缘节点返回,不再请求源站。这样可以显著降低延迟,并减少源站压力。

Cloudflare 性能优化主要围绕以下几个方向展开:

  1. 减少源站请求

    • 静态资源缓存
    • HTML 页面缓存
    • API 合理缓存
    • Cache Rules 精细化控制
  2. 缩小传输体积

    • Brotli / Gzip 压缩
    • JS、CSS、HTML 压缩
    • 图片 WebP / AVIF 优化
  3. 提升网络传输效率

    • HTTP/2
    • HTTP/3 QUIC
    • 0-RTT
    • Early Hints
  4. 缩短动态请求耗时

    • Worker 边缘缓存
    • KV / R2 边缘数据存储
    • Argo Smart Routing
  5. 优化浏览器缓存策略

    • 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 的缓存分为两层:

  1. 边缘缓存

    • Cloudflare 节点是否缓存资源
    • 缓存多久
  2. 浏览器缓存

    • 用户浏览器是否缓存资源
    • 缓存多久

良好的缓存策略可以大幅减少重复请求。


五、推荐的源站缓存头配置

如果你使用 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"
  • 一定要设置 widthheight,减少 CLS 布局偏移

3. 响应式图片源码


  
  
  Cloudflare 性能优化

浏览器会优先选择 AVIF,其次 WebP,最后 JPG。


十一、优化字体加载

字体文件也会影响首屏渲染。建议:

  1. 字体使用 WOFF2
  2. 只加载必要字重
  3. 使用 font-display: swap
  4. 对关键字体 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 缓存清理策略

缓存不是越久越好,关键是要可控。

常见清理方式:

  1. 手动 Purge Everything
  2. 按 URL 清理
  3. 按 Cache-Tag 清理
  4. 发布系统自动清理

如果是生产环境,不建议频繁使用 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 后,只关注速度,而忽略安全配置。实际上,安全规则如果配置不当,也可能影响性能。

建议:

  1. 不要对所有请求都启用高强度 Challenge
  2. 对静态资源不要启用复杂 WAF 检查
  3. 对 API 做限流,而不是一刀切阻断
  4. 后台路径单独设置访问规则
  5. 开启 Bot Fight Mode 前要观察误伤情况

例如可以给后台路径设置更严格规则:

(http.request.uri.path contains "/admin")

操作:

Managed Challenge

而静态资源路径:

/assets/*
/images/*
/fonts/*

则尽量避免复杂验证,否则会影响加载速度。


十九、性能测试方法

优化完成后,需要用数据验证效果。

推荐工具:

  1. Google PageSpeed Insights
  2. Lighthouse
  3. WebPageTest
  4. GTmetrix
  5. Chrome DevTools Network
  6. curl
  7. 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。


二十二、生产环境优化建议

最后给出一套更稳妥的生产实践:

  1. 先优化静态资源,再优化 HTML

    • 静态资源缓存风险低
    • HTML 缓存容易影响更新和登录态
  2. 所有静态资源文件名必须带 hash

    • 例如 app.a8c9e2.js
    • 避免用户拿到旧版本文件
  3. 缓存规则先小范围测试

    • 可以先对 /docs/*/blog/* 生效
    • 确认无误后再扩大范围
  4. 后台和用户相关路径必须 Bypass

    • 登录态页面不能公共缓存
  5. 发布系统集成缓存清理

    • 发布文章后清理文章页、首页、分类页
    • 不要频繁全站清理
  6. 持续观察 Analytics

    • 查看缓存命中率
    • 查看源站请求量
    • 查看错误率和响应时间

总结

Cloudflare 性能优化并不是简单地“打开 CDN”就结束了,而是需要结合网站类型、资源结构、更新频率和用户访问区域进行系统配置。

对于大多数网站,最值得优先完成的是:

  1. 开启 Brotli、HTTP/3、Early Hints
  2. 配置合理的源站 Cache-Control
  3. 使用 Cache Rules 缓存静态资源
  4. 对博客、文档类 HTML 页面设置短时间边缘缓存
  5. 排除登录、后台、支付、用户中心等动态页面
  6. 使用 Worker 实现更灵活的边缘缓存
  7. 发布时自动调用 API 清理缓存

如果配置得当,Cloudflare 可以显著提升网站访问速度,降低源站压力,并增强全球访问稳定性。对于内容型网站、企业官网、静态站点、博客系统而言,缓存命中率达到 80% 以上并不困难;对于动态业务系统,也可以通过 API 分级缓存、Worker 和 KV 等方式获得明显收益。

目录结构
全文