很多人说“网站很慢”,其实不是一个问题。
有的网站是图片太大,页面下载慢;有的是前端 JS 太多,浏览器渲染慢;还有一种更烦:页面一直白着,等一会儿才开始出来。
这种情况最该先看的不是带宽,也不是 CDN,而是 TTFB。
TTFB 是 Time To First Byte,中文一般叫“首字节时间”。简单说,就是浏览器发出请求后,多久收到服务器返回的第一个字节。
如果 TTFB 很高,说明慢点大概率发生在:
- DNS / TLS / 网络握手
- CDN 回源
- Nginx 反向代理
- PHP-FPM / Node / Python 应用
- 数据库查询
- 缓存没有命中
- VPS CPU、磁盘 I/O、内存压力
我之前帮人看过一个 WordPress 站,首页 TTFB 2.8 秒,图片压缩、换主题、开 Brotli 都折腾了一圈,结果最后是一个插件每次首页都查 400 多条数据库记录。把慢查询和对象缓存处理掉,TTFB 直接掉到 300ms 左右。
所以这篇不讲“网站加速十大技巧”,只讲一件事:TTFB 高时怎么定位到底卡在哪一层。
别凭感觉判断。
浏览器里打开开发者工具,进 Network,刷新页面,看主 HTML 请求的 Timing。
你重点看:
| 阶段 | 说明 |
|---|---|
| DNS Lookup | 域名解析耗时 |
| Initial connection | TCP 连接耗时 |
| SSL | TLS 握手耗时 |
| Waiting for server response | 通常就是 TTFB 核心部分 |
| Content Download | 内容下载耗时 |
如果慢的是 Content Download,那可能是页面太大、图片太大、带宽慢。
如果慢的是 Waiting for server response,才是这篇要处理的 TTFB 问题。
用命令也能测:
curl -o /dev/null -s -w 'dns:%{time_namelookup}\nconnect:%{time_connect}\ntls:%{time_appconnect}\nttfb:%{time_starttransfer}\ntotal:%{time_total}\n' https://example.com/
输出可能是:
dns:0.012
connect:0.080
tls:0.160
ttfb:2.431
total:2.620
这就很明显:真正慢的是首字节,不是下载。
TTFB 高不一定是服务器慢,也可能是链路问题。
至少从两个地方测:
curl -o /dev/null -s -w '%{time_starttransfer}\n' https://example.com/
可以在:
- 你本地电脑
- VPS 本机
- 另一个地区的服务器
- Cloudflare 后台 / WebPageTest / PageSpeed Insights
如果 VPS 本机访问自己很快:
curl -o /dev/null -s -w '%{time_starttransfer}\n' http://127.0.0.1/
但你本地访问很慢,那可能是:
- DNS 解析慢
- 跨境线路慢
- CDN 节点回源慢
- 晚高峰网络抖动
如果 VPS 本机访问也慢,那问题大概率在应用、Nginx、数据库或机器资源。
晚高峰相关可以看:VPS 晚高峰为什么会卡。
如果你用了 Cloudflare 或其它 CDN,先别急着怪源站。
你要分别测两条路径:
- 用户访问 CDN
- CDN 回源访问 VPS
如果域名走 Cloudflare,可以临时用源站 IP 测:
curl -H 'Host: example.com' -o /dev/null -s -w 'ttfb:%{time_starttransfer} total:%{time_total}\n' http://YOUR_ORIGIN_IP/
如果源站很快,但走 Cloudflare 慢,可能是:
- CDN 节点到源站链路慢
- Cloudflare 安全规则 / WAF 检查耗时
- 缓存规则没命中
- 回源协议、TLS、重定向配置有问题
如果源站本身就慢,那 CDN 只是把慢的问题暴露出来。
Cloudflare 源站问题可以参考:VPS 网站出现 Cloudflare 521 / 522 怎么办。
很多时候你需要知道:慢在 Nginx,还是 Nginx 后面的应用。
Nginx 默认日志不一定有这些字段,建议临时加一个更有用的 log_format:
log_format timing '$remote_addr - $host "$request" '
'status=$status request_time=$request_time '
'upstream_response_time=$upstream_response_time '
'upstream_connect_time=$upstream_connect_time '
'upstream_header_time=$upstream_header_time';
access_log /var/log/nginx/access_timing.log timing;
检查配置:
nginx -t
systemctl reload nginx
然后访问几次页面,再看:
tail -f /var/log/nginx/access_timing.log
你可能会看到:
status=200 request_time=2.845 upstream_response_time=2.801 upstream_header_time=2.801
这说明大部分时间花在上游应用。
如果是:
request_time=2.800 upstream_response_time=-
那可能是静态文件、Nginx 自己处理、连接等待或其它配置问题。
Nginx 配置出错可以看:VPS Nginx 配置错误怎么办。
如果你跑的是 WordPress、Laravel、Typecho 这类 PHP 站,TTFB 高经常出在 PHP-FPM。
先看服务状态:
systemctl status php8.2-fpm
看日志:
journalctl -u php8.2-fpm -n 100 --no-pager
版本号按你的系统改,比如 php8.1-fpm、php8.3-fpm。
重点看这些信号:
server reached pm.max_children setting
child exited on signal
slow request
pool www seems busy
如果看到 pm.max_children 打满,说明 PHP worker 不够或者单个请求太慢。
可以看进程数量:
ps aux | grep php-fpm | wc -l
也可以开启 PHP-FPM slowlog:
request_slowlog_timeout = 5s
slowlog = /var/log/php-fpm/www-slow.log
然后 reload PHP-FPM。
WordPress 站点慢,可以继续看:VPS 上 WordPress 很慢怎么办。
如果页面每次都要查数据库,数据库慢一点,TTFB 就会直接上去。
MySQL / MariaDB 先看慢查询日志有没有开:
SHOW VARIABLES LIKE 'slow_query_log';
SHOW VARIABLES LIKE 'long_query_time';
临时开启可以这样:
SET GLOBAL slow_query_log = 'ON';
SET GLOBAL long_query_time = 1;
然后看慢查询日志位置:
SHOW VARIABLES LIKE 'slow_query_log_file';
常见问题:
- 缺索引
- 插件或主题重复查询
- 首页一次查太多数据
- 数据库和应用不在同一个区域
- 数据库连接池不够
- 表太大但没有分页
如果你不想马上分析 SQL,至少先看数据库有没有压力:
top
iotop -o
mysqladmin processlist
数据库连接不上或启动失败,不是同一个问题,可以看:VPS MySQL / MariaDB 连接不上怎么办。
很多小站 TTFB 高,不是机器差,而是缓存没配好。
你可以先看响应头:
curl -I https://example.com/
关注这些:
cache-control
cf-cache-status
x-cache
server-timing
如果你用了 Cloudflare,但 HTML 页面一直是:
cf-cache-status: DYNAMIC
那说明 Cloudflare 没缓存 HTML,它每次都回源。
这对后台、购物车、登录页是正常的;但如果是纯内容页、博客页、文档页,就可以考虑缓存。
Nginx 也可以用 fastcgi_cache 或 proxy_cache,但要小心:
- 登录用户不要缓存
- 后台不要缓存
- 带用户态 Cookie 的页面不要乱缓存
- 表单、支付、评论提交不要缓存
缓存做错会比不做更麻烦。
很多人看 top,发现 CPU 不高,就觉得机器没问题。
但 TTFB 高可能卡在:
- 磁盘 I/O
- iowait
- 内存回收
- swap 抖动
- PHP-FPM worker 排队
- 数据库锁等待
看系统负载:
uptime
看 CPU、内存、iowait:
vmstat 1
看磁盘 I/O:
iostat -xz 1
看进程:
htop
如果 wa 很高,或者磁盘 util 长时间接近 100%,请求可能都在等磁盘。
这种情况可以看:VPS 磁盘 I/O 很高怎么办。
TTFB 是从请求开始算到第一个字节,有时候前面 DNS、连接、TLS 就已经慢了。
用 curl 可以拆开看:
curl -o /dev/null -s -w 'dns:%{time_namelookup}\nconnect:%{time_connect}\ntls:%{time_appconnect}\nttfb:%{time_starttransfer}\ntotal:%{time_total}\n' https://example.com/
如果 dns 就 0.8 秒,那不是 PHP 慢。
如果 tls 很高,可能是:
- 证书链问题
- HTTPS 跳转多次
- 源站和 CDN SSL 模式不合适
- HTTP/2 / HTTP/3 配置异常
检查跳转链:
curl -IL https://example.com/
如果出现 http -> https -> www -> non-www -> https 这种来回跳,TTFB 看起来也会很难看。
HTTPS 跳转循环可以看:VPS 网站 HTTPS 跳转循环怎么办。
首页 TTFB 正常,不代表接口正常。
很多站真正慢的是:
/api/search/wp-admin/admin-ajax.php/api/orders/graphql- 登录接口
- 后台列表页
分别测:
curl -o /dev/null -s -w 'ttfb:%{time_starttransfer} total:%{time_total}\n' https://example.com/api/search
如果只有某个接口慢,就不要全站乱优化。直接查这个接口:
- 是否查数据库太多
- 是否调用外部 API
- 是否没有缓存
- 是否锁等待
- 是否被限流或 WAF 检查
我见过一个站首页很快,搜索接口 TTFB 6 秒,最后发现每次搜索都实时请求第三方 API。你换再贵的 VPS,也只是把 6 秒变成 5.8 秒。
你可以按这个顺序走:
# 1. 拆开 DNS、连接、TLS、TTFB、总耗时
curl -o /dev/null -s -w 'dns:%{time_namelookup}\nconnect:%{time_connect}\ntls:%{time_appconnect}\nttfb:%{time_starttransfer}\ntotal:%{time_total}\n' https://example.com/
# 2. 在 VPS 本机测源站
curl -o /dev/null -s -w 'ttfb:%{time_starttransfer} total:%{time_total}\n' http://127.0.0.1/
# 3. 绕过 CDN 测源站 IP
curl -H 'Host: example.com' -o /dev/null -s -w 'ttfb:%{time_starttransfer} total:%{time_total}\n' http://YOUR_ORIGIN_IP/
# 4. 看 Nginx 访问时间字段
tail -f /var/log/nginx/access_timing.log
# 5. 看应用日志
journalctl -u php8.2-fpm -n 100 --no-pager
# 6. 看系统资源
vmstat 1
iostat -xz 1
然后按结果判断:
| 现象 | 优先查什么 |
|---|---|
| DNS 慢 | DNS 服务商、解析链路、本地网络 |
| TLS 慢 | 证书链、跳转、CDN SSL 模式 |
| 源站本机也慢 | 应用、PHP-FPM、数据库、I/O |
| 源站快,CDN 慢 | CDN 回源、缓存规则、WAF |
| upstream_response_time 高 | 后端应用或数据库 |
| request_time 高但 upstream 低 | Nginx、客户端、下载、限速 |
| 某个接口慢 | 查接口逻辑、SQL、外部 API |
TTFB 高当然可能是机器太弱,但不是第一结论。
适合升级机器的情况:
- CPU 长时间满
- 内存不足频繁 swap
- 磁盘 I/O 长时间打满
- 数据库已经优化过但资源不够
- PHP-FPM worker 合理配置后仍然排队
不适合靠升级解决的情况:
- 某个插件写了慢 SQL
- 每次请求都调外部 API
- Cloudflare 没缓存静态内容
- Nginx 反代配置错误
- 页面跳转链混乱
- 数据库缺索引
升级 VPS 有时只是把问题往后推一个月。真正该做的是先定位慢在哪一层。
如果你正在排查网站 TTFB,下面几篇可以接着看:
- VPS 上 WordPress 很慢怎么办
- VPS 出现 502 / 504 Bad Gateway 怎么办
- VPS Nginx 配置错误怎么办
- VPS 磁盘 I/O 很高怎么办
- VPS 网站出现 Cloudflare 521 / 522 怎么办
最后给个最实用的判断:如果 curl 里 time_starttransfer 高,但 time_total 没比它高多少,重点查后端生成页面;如果 time_starttransfer 不高但 time_total 高,重点查下载体积、图片、带宽和前端资源。先把这两个分清,能少走一大半弯路。
