同样的症状,相反的病因
两个站都出现了同样的抱怨:切换页面不灵敏,点一下要等一会儿,延迟感很重。按直觉,这种问题多半是服务器配置不够、该升级了。但真正测完之后发现,两站的病根正好相反——一个慢在服务器生成,一个慢在网络和图片。先测再改,是这次优化里最大的教训。
Workers 站:时间全花在等第一个字节
aibochinese.com 是一个对外汉语教学站,跑在 Cloudflare Workers 上。实测文章页总耗时约 2.9 秒,其中等待服务器返回第一个字节(TTFB)就占了 2.7 秒,页面下载只花 0.15 秒。也就是说,绝大部分时间不是网速问题,而是服务器在“想”。
三个病因
- 每次打开列表页,要串行跑约 10 次数据库查询,一次等完再等下一次。
- 列表为了判断每篇文章有没有视频,把 20 篇文章的完整正文都拉出来扫一遍,合计约 368KB,平均每篇 23.7KB,最大一篇 148KB。
- 每页内联 12 段脚本,约 32KB,每次切换页面都要重复下载和解析。
三档改法
一档,先砍掉最贵的浪费。视频信息改成保存文章时预先算好、存进字段,列表只查轻字段;分页改成无刷新换页,只换 13KB 的列表片段(整页 66KB),并预取下一页。
二档,减少重复查询和重复下载。站点信息改内存缓存,每页省掉约 16 次重复查询;样式和脚本改长缓存,两个大脚本外置,内联脚本从 32.6KB 降到 22KB。
三档,把能缓存的推到边缘。游客页面在边缘缓存 2 分钟,登录用户绕过、按语言分开;文章表加排序索引。
效果
文章页 TTFB 从 2.7 秒降到 1.4 秒,列表片段生成只要 0.44 秒,点页码基本即时;VIP 页、分类页、图书馆页的 TTFB 都降到 1.0–1.4 秒。
PHP 站:服务器很快,路太远、图太大
opcgrow.org 是一个自研 PHP 站,服务器在洛杉矶。在服务器本机测,页面生成只要 15–25 毫秒,每页就 2–5 次查询,服务器一点也不慢。但公网 TTFB 有 0.3–0.7 秒,国内用户还要更久——慢在跨太平洋的网络往返和图片上。
三个病因
- 全站每个页面都开 PHP 会话,响应头是 no-store,CDN 边缘完全不缓存 HTML,每次切页都要回洛杉矶取一趟。
- 图片原图直出,没有缩略图。首页 26 张图约 14.8MB,其中导航栏一个小 logo 竟是 3MB 的 PNG;全站 238 张文章图里,61 张超过 500KB。
- 列表图没有懒加载,页面一打开就全量下载。
三档改法
一档,图片瘦身。为 241 张图批量生成 WebP 缩略图,原图合计 176.6MB,缩略图合计只有 7.66MB;logo 换成 192KB 的 WebP;列表图加懒加载;后台上传时自动生成缩略图。
二档,让边缘敢缓存。会话改懒启动,游客没带 Cookie 就不开会话;游客页面发 120 秒的边缘缓存标记。Cloudflare 缓存规则接口权限不足,改用一个小 Worker 做边缘缓存,只缓存游客的公开页面,带会话 Cookie 的一律绕过。游客评论原本靠页面里的 CSRF 令牌,改成点提交时现取令牌,游客评论功能保住了。
三档,优化手感。站内链接在悬停/触摸时预取;文章列表分页改无刷新换页;Service Worker 改成先出缓存、后台更新。
效果
首页图片总量从 14.8MB 降到 1.85MB,降了 87%;边缘缓存命中时 TTFB 约 0.33 秒。
六条经验
- 先测再改。把 TTFB 和下载耗时分开测,再到服务器本机测生成耗时;同样的症状病根可能完全相反,测错了方向,钱就白花。
- 列表页永远不要拉全文。要展示什么,就预计算什么。
- 图片是老站最常见的隐形杀手。缩略图+WebP+懒加载是性价比最高的一档,连 logo 都要查一眼大小。
- 游客流量尽量交给边缘缓存。前提是把会话、CSRF 这类个性化依赖从页面里拆出来。
- 手感优化放最后做。预取、无刷新换页、Service Worker 是锦上添花,不是雪中送炭。
- 每一档做完都复测对比、留好备份。效果用数字说话,别用感觉说话。
写在最后
两个站都没花一分钱升级服务器。慢的问题,大半出在用法,而不是配置。
评论区
0 条评论 · 评论需审核通过后显示
发表评论