切个页面要等好几秒 —— 用 curl 把耗时拆开一量,真凶不是网站大,而是跨国线路 + 两个配置缺陷。修完切页零网络请求。
本站(服务器在美国洛杉矶)出现「点导航要等好一会才切换」的问题。凭感觉猜没用,直接上 curl 把一次请求的耗时拆开看:
curl -s -o /dev/null -w "DNS: %{time_namelookup}s
TCP: %{time_connect}s
TLS: %{time_appconnect}s
首字节: %{time_starttransfer}s
总耗时: %{time_total}s" https://example.com/
测量结果:真凶现形
- 首页 81KB(gzip 后约 20KB)—— 页面不大,不是它的锅
- TLS 握手 1.67 秒(正常应在 0.1 秒内)—— 高延迟线路上完整握手要来回好几趟
- 一个 18KB 的 JS 文件跑了 6.2 秒 —— 这种剧烈波动只有一个解释:跨国线路晚高峰拥塞丢包
- 响应头里没有任何缓存指令 —— 每次切页,浏览器把所有文件原样重新下载一遍,每个文件都要跨一次太平洋
结论:大头是物理距离(用户在国内、服务器在洛杉矶,低价 VPS 走普通线路非 CN2),但配置缺陷把痛苦放大了好几倍。
三板斧(只改 nginx,不动代码)
- 加缓存头:页面
Cache-Control: max-age=600(10 分钟),静态资源 1 小时,需要实时的数据文件no-cache。效果:首次加载后,站内切页零网络请求,直接读本地缓存。 - TLS 会话复用:
ssl_session_cache shared:SSL:10m;—— 二次连接跳过完整握手,高延迟线路上立省近 1 秒。 - gzip 调优:
gzip_comp_level 6+ 补全gzip_types+gzip_vary on。
效果
| 指标 | 修复前 | 修复后 |
|---|---|---|
| TLS 握手 | 1.67s | 0.78s |
| 首页总耗时 | 2.31s | 1.41s |
| 站内切页 | 每次全量重下 | 本地缓存,零请求 |
如果还想更快:CDN
跨国延迟是物理规律,服务器端再怎么调也省不掉光速。根治方案是把域名接入 CDN(如 Cloudflare 免费版):静态内容缓存到离访客近的边缘节点,不再每次跨太平洋。纯静态站效果尤其明显,代价只是把 DNS 托管迁过去。
方法论比结论重要:觉得慢,先量化,再动手 —— curl 的 -w 参数把一次请求拆成 DNS / TCP / TLS / 首字节四段,哪段超标修哪段,不靠猜。