CDN 与 WAF 精讲教程 / 第05章 CDN 性能优化
第05章 CDN 性能优化
本章聚焦 CDN 层面的性能优化技术,涵盖图片优化、压缩算法、协议升级和连接优化,帮助你榨干每一毫秒的性能。
5.1 图片优化
5.1.1 图片格式对比
| 格式 |
压缩方式 |
透明度 |
动画 |
浏览器支持 |
适用场景 |
| JPEG |
有损 |
❌ |
❌ |
全部 |
照片、复杂图像 |
| PNG |
无损 |
✅ |
❌ |
全部 |
Logo、图标、截图 |
| GIF |
无损 |
✅ |
✅ |
全部 |
简单动画 |
| WebP |
有损+无损 |
✅ |
✅ |
96%+ |
现代浏览器首选 |
| AVIF |
有损+无损 |
✅ |
✅ |
90%+ |
最高压缩率 |
| SVG |
矢量 |
✅ |
✅ |
全部 |
图标、图表 |
5.1.2 现代图片策略
响应式图片加载策略:
用户请求 image.jpg
│
▼
┌─────────────────────────────────────┐
│ CDN 边缘图片优化引擎 │
│ │
│ 1. 检测 Accept 头 │
│ ├── 支持 AVIF → 返回 image.avif │
│ ├── 支持 WebP → 返回 image.webp │
│ └── 仅 JPEG → 返回 image.jpg │
│ │
│ 2. 检测设备尺寸 │
│ ├── 移动端 → 宽度 640px │
│ ├── 平板 → 宽度 1024px │
│ └── 桌面 → 宽度 1920px │
│ │
│ 3. 质量参数 │
│ ├── 高带宽 → quality=85 │
│ └── 低带宽 → quality=60 │
└─────────────────────────────────────┘
5.1.3 HTML 响应式图片
<picture>
<!-- AVIF 优先 -->
<source
type="image/avif"
srcset="/image/photo-640w.avif 640w,
/image/photo-1280w.avif 1280w,
/image/photo-1920w.avif 1920w"
sizes="(max-width: 640px) 640px,
(max-width: 1280px) 1280px,
1920px">
<!-- WebP 其次 -->
<source
type="image/webp"
srcset="/image/photo-640w.webp 640w,
/image/photo-1280w.webp 1280w,
/image/photo-1920w.webp 1920w"
sizes="(max-width: 640px) 640px,
(max-width: 1280px) 1280px,
1920px">
<!-- JPEG 兜底 -->
<img src="/image/photo-1280w.jpg"
alt="Photo"
loading="lazy"
decoding="async"
width="1280" height="720">
</picture>
5.1.4 图片优化效果参考
| 原始格式 |
原始大小 |
WebP (q=80) |
AVIF (q=50) |
节省比例 |
| JPEG 2MB |
2,000 KB |
800 KB |
400 KB |
60-80% |
| PNG 500KB |
500 KB |
200 KB |
150 KB |
60-70% |
| PNG 50KB (图标) |
50 KB |
30 KB |
25 KB |
40-50% |
5.2 压缩算法
5.2.1 压缩算法对比
| 算法 |
压缩率 |
压缩速度 |
解压速度 |
浏览器支持 |
说明 |
| Brotli |
最高 |
慢 |
快 |
96%+ |
Google 开发,现代首选 |
| Gzip |
中等 |
快 |
快 |
全部 |
经典方案,兼容性最好 |
| Zstandard |
高 |
快 |
快 |
实验中 |
Facebook 开发 |
5.2.2 Brotli 压缩级别
| 级别 |
压缩率 |
CPU 消耗 |
适用场景 |
| 1 |
~70% |
极低 |
实时压缩(边缘) |
| 4 |
~75% |
低 |
一般网站 |
| 6 |
~78% |
中等 |
推荐级别 |
| 9 |
~82% |
高 |
静态资源预压缩 |
| 11 |
~83% |
极高 |
离线压缩(构建时) |
5.2.3 Nginx Brotli 配置
# 动态 Brotli 压缩
brotli on;
brotli_comp_level 6;
brotli_types text/plain text/css application/json
application/javascript text/xml
application/xml application/xml+rss
text/javascript image/svg+xml;
# 预压缩静态文件(构建时生成 .br 文件)
brotli_static on;
# Gzip 作为降级方案
gzip on;
gzip_comp_level 6;
gzip_types text/plain text/css application/json
application/javascript text/xml
application/xml text/javascript;
gzip_vary on;
gzip_min_length 256;
5.2.4 压缩效果实测
测试资源: 典型 React SPA 首页
原始大小: 2.4 MB (未压缩)
┌─────────────┬──────────┬──────────┬───────────┐
│ 算法 │ 压缩后 │ 压缩率 │ 压缩耗时 │
├─────────────┼──────────┼──────────┼───────────┤
│ 不压缩 │ 2,400 KB │ 0% │ 0ms │
│ Gzip (6) │ 620 KB │ 74% │ 8ms │
│ Brotli (6) │ 510 KB │ 79% │ 15ms │
│ Brotli (11) │ 460 KB │ 81% │ 120ms │
└─────────────┴──────────┴──────────┴───────────┘
5.3 HTTP/2 与 HTTP/3
5.3.1 HTTP 协议演进
HTTP/1.1 (1997) HTTP/2 (2015) HTTP/3 (2022)
┌────────────────┐ ┌────────────────┐ ┌────────────────┐
│ 文本协议 │ │ 二进制帧 │ │ 基于 QUIC │
│ 串行请求 │ │ 多路复用 │ │ 多路复用 │
│ 无头部压缩 │ │ HPACK 头部压缩 │ │ QPACK 头部压缩 │
│ 无服务器推送 │ │ 服务器推送 │ │ 服务器推送 │
│ TCP 连接 │ │ TCP 连接 │ │ UDP (QUIC) │
│ 队头阻塞 │ │ TCP 层队头阻塞 │ │ 无队头阻塞 │
└────────────────┘ └────────────────┘ └────────────────┘
5.3.2 HTTP/2 核心优势
| 特性 |
HTTP/1.1 |
HTTP/2 |
收益 |
| 多路复用 |
6-8 个 TCP 连接 |
1 连接多流 |
消除队头阻塞 |
| 头部压缩 |
无(每次全量) |
HPACK 静/动态表 |
减少 30-50% 头部 |
| 二进制帧 |
文本解析 |
二进制解析 |
更高效 |
| 服务器推送 |
不支持 |
Push 资源到客户端 |
减少往返 |
| 流优先级 |
无 |
权重 + 依赖树 |
关键资源优先 |
5.3.3 Nginx HTTP/2/3 配置
# HTTP/2
server {
listen 443 ssl http2;
server_name example.com;
ssl_certificate /etc/ssl/certs/example.com.crt;
ssl_certificate_key /etc/ssl/private/example.com.key;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers HIGH:!aNULL:!MD5;
# HTTP/3 (QUIC)
listen 443 quic reuseport;
add_header Alt-Svc 'h3=":443"; ma=86400';
# 启用 HTTP/2 Server Push(谨慎使用)
location /index.html {
http2_push /style/main.css;
http2_push /script/app.js;
}
}
5.3.4 HTTP/3 (QUIC) 注意事项
| 优势 |
限制 |
| 0-RTT 连接建立 |
UDP 可能被部分网络封锁 |
| 连接迁移(Wi-Fi → 4G) |
CPU 消耗略高于 TCP |
| 无 TCP 队头阻塞 |
生态仍在完善 |
| 内置 TLS 1.3 |
需要客户端/CDN 同时支持 |
5.4 预连接与资源提示
5.4.1 Resource Hints
<head>
<!-- DNS 预解析:提前解析域名 -->
<link rel="dns-prefetch" href="//cdn.example.com">
<link rel="dns-prefetch" href="//analytics.example.com">
<!-- 预连接:DNS + TCP + TLS(比 dns-prefetch 更进一步) -->
<link rel="preconnect" href="https://cdn.example.com">
<link rel="preconnect" href="https://api.example.com" crossorigin>
<!-- 预获取:提前获取可能需要的页面 -->
<link rel="prefetch" href="/next-page.html">
<!-- 预加载:当前页面关键资源,必须加载 -->
<link rel="preload" href="/font/main.woff2" as="font" type="font/woff2" crossorigin>
<link rel="preload" href="/style/critical.css" as="style">
<link rel="preload" href="/image/hero.avif" as="image" type="image/avif">
</head>
5.4.2 Resource Hints 对比
| 指令 |
作用 |
优先级 |
时机 |
dns-prefetch |
仅 DNS 解析 |
低 |
浏览器空闲时 |
preconnect |
DNS + TCP + TLS |
中 |
尽快 |
preload |
当前页面必须资源 |
高 |
立即 |
prefetch |
下一页可能需要的资源 |
最低 |
浏览器空闲时 |
prerender |
预渲染整个页面 |
— |
浏览器决定 |
5.4.3 性能影响估算
典型优化效果(以首次访问为例):
无优化:
DNS 解析 → TCP 握手 → TLS 握手 → HTTP 请求 → 响应
50ms 50ms 50ms 10ms 100ms
总计: ~260ms
启用 preconnect:
[DNS+TCP+TLS 已提前完成] → HTTP 请求 → 响应
0ms (预连接完成) 10ms 100ms
总计: ~110ms(节省 ~150ms)
启用 preload (关键 CSS):
[关键 CSS 已提前下载] → 首屏渲染 → 非关键资源异步加载
0ms 首屏快 200-500ms
5.5 TLS 优化
5.5.1 TLS 握手优化
| 技术 |
说明 |
收益 |
| TLS 1.3 |
1-RTT 握手(TLS 1.2 为 2-RTT) |
减少 1 次往返 |
| 0-RTT |
恢复连接时零往返(配合 TLS 1.3) |
首字节更快 |
| OCSP Stapling |
服务器预取 OCSP 响应 |
减少客户端验证延迟 |
| Session Resumption |
复用 TLS 会话 |
跳过密钥交换 |
| Certificate Compression |
压缩证书链 |
减少握手数据量 |
5.5.2 Nginx TLS 优化配置
server {
# TLS 1.3 + 0-RTT
ssl_protocols TLSv1.2 TLSv1.3;
ssl_early_data on; # 0-RTT
# OCSP Stapling
ssl_stapling on;
ssl_stapling_verify on;
ssl_trusted_certificate /etc/ssl/certs/ca-chain.crt;
resolver 8.8.8.8 8.8.4.4 valid=300s;
# Session 复用
ssl_session_cache shared:SSL:50m;
ssl_session_timeout 1d;
ssl_session_tickets on;
# 现代密码套件
ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384;
ssl_prefer_server_ciphers on;
# ECDH 曲线
ssl_ecdh_curve X25519:secp384r1:secp256r1;
}
5.6 边缘计算优化
5.6.1 边缘计算场景
| 场景 |
技术 |
说明 |
| A/B 测试 |
Cookie 注入 + 重写 |
边缘分流,无需回源 |
| URL 重写 |
边缘路由规则 |
减少回源 |
| 认证鉴权 |
JWT 验证 |
边缘校验 Token |
| 个性化 |
边缘渲染 |
ESI / Edge SSR |
| API 聚合 |
边缘组合多 API |
减少客户端请求数 |
| 地理限制 |
GeoIP + 重定向 |
边缘判断地理位置 |
5.6.2 Cloudflare Workers 示例
// 边缘 JWT 验证示例
export default {
async fetch(request) {
const url = new URL(request.url);
// 不需要认证的路径
const publicPaths = ['/login', '/register', '/health'];
if (publicPaths.includes(url.pathname)) {
return fetch(request);
}
// 验证 JWT
const token = request.headers.get('Authorization')?.replace('Bearer ', '');
if (!token) {
return new Response(JSON.stringify({ error: 'Unauthorized' }), {
status: 401,
headers: { 'Content-Type': 'application/json' }
});
}
try {
const payload = await verifyJWT(token);
// 将用户信息添加到请求头,传递给源站
const modifiedRequest = new Request(request, {
headers: {
...Object.fromEntries(request.headers),
'X-User-Id': payload.sub,
'X-User-Role': payload.role,
}
});
return fetch(modifiedRequest);
} catch (e) {
return new Response(JSON.stringify({ error: 'Invalid token' }), {
status: 403,
headers: { 'Content-Type': 'application/json' }
});
}
}
}
5.7 性能监控指标
5.7.1 核心 Web 指标 (Core Web Vitals)
| 指标 |
英文全称 |
良好阈值 |
衡量维度 |
| LCP |
Largest Contentful Paint |
< 2.5s |
加载速度 |
| INP |
Interaction to Next Paint |
< 200ms |
交互响应 |
| CLS |
Cumulative Layout Shift |
< 0.1 |
视觉稳定性 |
| TTFB |
Time to First Byte |
< 800ms |
服务器响应 |
| FCP |
First Contentful Paint |
< 1.8s |
首次渲染 |
5.7.2 CDN 层面监控
| 指标 |
说明 |
目标值 |
| Cache Hit Ratio |
缓存命中率 |
> 85% |
| Edge Latency |
边缘处理延迟 |
< 10ms |
| Origin Latency |
回源延迟 |
< 200ms |
| Bandwidth Saved |
带宽节省比例 |
> 70% |
| Error Rate |
5xx 错误率 |
< 0.1% |
5.8 注意事项
⚠️ 0-RTT 重放攻击:TLS 1.3 的 0-RTT 数据可被重放,不应用于非幂等请求(如 POST、支付)。
⚠️ HTTP/2 Server Push:已被 Chrome 移除支持,建议改用 103 Early Hints。
⚠️ Brotli 动态压缩:级别 10-11 的 CPU 消耗极高,仅用于构建时预压缩,不适合实时压缩。
⚠️ 图片格式兼容:AVIF 虽压缩率最高,但旧浏览器不支持,务必提供 WebP/JPEG 兜底。
5.9 扩展阅读
本章小结
| 主题 |
核心要点 |
| 图片优化 |
WebP/AVIF 格式优先 + 响应式尺寸 |
| 压缩 |
Brotli 6 级动态压缩,11 级静态预压缩 |
| HTTP/2+ |
多路复用 + 头部压缩 + TLS 1.3 |
| 预连接 |
preconnect/preload 减少关键路径延迟 |
| 边缘计算 |
在边缘处理认证、路由、个性化 |
下一章:第06章 WAF 基础原理 →