我自己打开一直很快,因为浏览器有缓存。从北京发一次没有缓存的请求:首字节 1.3 秒,整页 4 秒,最差一次 24 秒。换到香港一台小机器后,整页 0.3 秒。
这个站是拿来投简历的。静态页,没有数据库,之前挂在一个免费 CDN 的静态托管上。我每次打开都很快,页面几乎立刻就出来——现在回头看,那只是缓存:脚本、样式、HTML 都在本机存过一份。
真正的问题要用没有缓存的请求才测得出来。从北京发一次首访:首字节 1.3 秒,整页 4 秒,最差的一次 24 秒;360 KB 的脚本 25 秒内一个字节都没到,样式表卡在半路。查路由,接入的边缘节点落在洛杉矶。同一时刻从境外六个节点测,0.2–0.5 秒,全都正常。
结论不是代码慢,是那家免费 CDN 在国内没有节点,流量要跨境,跨境链路一丢包,页面就散架。对一个主要给国内读者看的网站,这不是优化项,是能不能打开的问题。
01选一个能落地的方案
摆在面前的几条路:内地服务器延迟最低,但要备案,材料、审核、主体信息一堆;香港的小机器不用备案,物理距离近;还有更便宜的小机房,价格很诱人,但评价和稳定性都没法验证;家里的机器也想过,没有公网地址,走隧道最后还是绕回跨境。
最后选了香港一台 2 核 2G 的小机器,月付几十块。北京 ping 45–53 毫秒、零丢包;从国内机器实测性能已经够用,就不想为省二十块去赌一个说不清的机房。
02迁移
站点本来就是构建期预渲染的静态文件,迁移主要是把产物同步过去。服务器上只装一个轻量 Web 服务器:自动申请和续期证书,HTTP 跳 HTTPS,把 /about 映射到 about.html,找不到的路径回 404 页,静态资源给一年的不可变缓存,HTML 每次回源确认。
顺手做了该做的加固:只开 22、80、443 三个端口,SSH 只认密钥,登录失败自动封 IP,系统更新自动安装。机器只干这一件事。
发布做成一条命令:本地构建,然后增量同步到服务器。构建里带着双语完整性检查和类型检查,任何一项不过就发不出去。
域名改成只做解析、不再走 CDN 代理。否则流量还是被送回海外边缘,前面的迁移就白做了。
有一处依赖需要补:浏览量原来读写托管平台自带的键值存储,迁走之后接口直接 404。解决办法是在服务器上把 /api/* 反向代理回原平台,前端一行没改,数字接着涨。
03结果
北京:首字节 0.22–0.29 秒,整页 0.30–0.39 秒,147 KB 的脚本 0.51 秒,冷启动约 0.7 秒。十五个海外节点全部返回 200:东南亚 0.18–0.21 秒,美东 0.65 秒,欧洲 0.6–0.9 秒,巴西 1.16 秒。
代价说清楚。单点香港对欧洲、南美比全球 CDN 慢几百毫秒,静态资源有一年缓存,回访感觉不出来。原平台自带的 DDoS 防护没有了,纯静态站被打主要损失带宽,风险可以接受;原平台留着一个镜像,真出事改一下解析就能切回去。
还有一个操作上的代价:推送不等于上线。代码推上去只更新镜像,线上要再跑一次发布。这条我写进了仓库的操作手册,免得三个月后自己踩。
复盘只有一句:自己设备上的缓存会替真实网络说谎。站点给谁看,就从谁的网络、用没有缓存的请求去测。这次要不是先打了一次裸请求,这份简历可能一直以四秒的首访发出去。