首次加载 19 MB,国内要等几分钟:先量,再动手
我练手做的一个 3D 网页程序部署在新加坡的一台小服务器上。朋友反馈第一次打开要等很久,有人等了十分钟也没加载完。
先确认文件本身不大
页面要下载的大头是两个文件:引擎的 .wasm 和资源包 .pck。服务器上已经放好了 brotli 预压缩版本,浏览器带 Accept-Encoding: br 时拿到的是压缩后的文件:
| 文件 | 原始大小 | brotli 后 |
|---|---|---|
| index.wasm | 39.5 MB | 6.9 MB |
| index.pck | 15.8 MB | 11.9 MB |
合计约 19 MB。我从美国的网络测,10 秒左右就能下完,所以服务器和压缩都没问题,问题出在线路上。
用访问日志量真实速度
原来的配置没开访问日志,所以看不到别人到底有多慢。我在 Caddy 的站点块里加了 JSON 格式的访问日志,每个请求都会记下 duration(秒)和 size(字节):
log {
output file /var/log/caddy/site.log {
roll_size 20MiB
roll_keep 5
}
format json
}
过几天后,筛出完整下载 .pck 的请求,用 size ÷ duration 算出速度:113 次下载里,中位数只有约 82 KB/s,77 次超过了一分钟。
有个小坑:别用 root 身份跑 caddy validate。校验时它会先把日志文件建出来,属主就变成了 root,之后以 caddy 用户运行的服务打不开这个文件,reload 直接失败。
试过的两个改动
- 换 BBR 拥塞控制。默认的 cubic 把丢包当成拥塞,一丢包就降速;跨境线路丢包多,BBR 应付得更好。打开方法是
net.core.default_qdisc=fq加上net.ipv4.tcp_congestion_control=bbr。 - 关掉 HTTP/3。Caddy 默认会通过
alt-svc宣告 HTTP/3,可云厂商的防火墙并没有放行 UDP 443,浏览器白白试一次 QUIC 才退回 TCP。在全局配置里写servers { protocols h1 h2 }就能关掉。
两个都上了以后,日志里的速度并没有明显变好。这说明瓶颈在跨境链路本身,服务器上的参数救不了。
结论
想要国内用户打开快,服务器就要放在国内,或者把大文件放到国内的分发节点上。这两种做法都要先办 ICP 备案,这个站点就是为此准备的。
另外记一笔:从家里往服务器传文件,上行只有十几 KB/s,可服务器之间互相拉文件能到每秒十几 MB。所以发新版本时,我改成让新服务器从旧服务器拉,不再从家里直接推。