性能小抄:查询、缓存、静态资源加载优化

小助手
小助手 揽星漫步繁花
社区会员
教程 23 浏览 0 回复

上周帮朋友看一个 Xiuno BBS 站点,首页 TTFB 到了 1.8 秒,打开帖子列表要等三四秒。服务器配置不差,2 核 4G,问题全出在代码和资源加载上。这篇不讲虚的,直接把我改完的六个点列出来,每个都能单独拿去用。

一、帖子列表别在循环里查用户

最常见的问题:先查出一页帖子,然后 foreach 里每条帖子查一次用户名和头像。20 条帖子就是 20 次查询,加上其他钩子,首页轻松上百次 SQL。正确做法是把这页所有帖子的 uid 收集起来,用 IN 一次查完,再在 PHP 侧按 uid 组装。Xiuno 里可以用 user_read_by_uids() 这类批量读取函数,或者自己写一条 SELECT uid, username, avatar FROM bbs_user WHERE uid IN (...)。改完后首页查询从 100+ 降到 8 条左右。

二、给高频查询加一层文件缓存

不是所有数据都要实时。版块列表、热门标签、站点统计这些变化不频繁的数据,读一次数据库后写进缓存,设个 300 秒过期。Xiuno 自带 cache_set() / cache_get(),底层是文件缓存,够用。写法上注意两点:一是缓存 key 要带版本号,改数据时递增版本号比逐个删 key 省事;二是空结果也要缓存,否则一个不存在的版块被反复请求时会一直打数据库。

三、静态资源合并与版本号

打开页面源码数一下 <link> 和 <script> 标签数量。很多站点 css 和 js 各十几个文件,每个都是独立请求。能合并的合并成两个文件(一个 css、一个 js),不能合并的用 defer 加载。同时给资源 URL 加上版本号参数,比如 style.css?v=20260921,这样改完资源浏览器会强制拉新,不用手动清缓存。Xiuno 的模板里可以用 {$static_url} 配合版本变量统一处理。

四、图片懒加载和尺寸占位

帖子列表里的缩略图如果直接 <img src="...">,浏览器会一次性全加载。换成 loading="lazy" 属性,现代浏览器原生支持,不用引 JS 库。更关键的是给图片容器写死宽高,或者用 aspect-ratio,否则图片加载完成前页面会跳动,用户滚动时体验很差。这一步不减少请求数,但能明显降低感知延迟。

五、把非关键脚本挪到 body 末尾

统计代码、客服悬浮窗、分享按钮的脚本,全部从 <head> 挪到 </body> 前面。这些脚本不参与首屏渲染,放头部只会阻塞。如果某个脚本必须提前加载,加 async 或 defer。我改的那站把百度统计和两个第三方组件挪走后,首屏渲染时间从 1.2 秒降到 0.6 秒。

六、用 explain 确认索引真的走了

加索引之前先 EXPLAIN 一下你的慢查询。Xiuno 的帖子表按 fid、tid 查是常规操作,但排序字段如果没索引,MySQL 会 filesort。比如 ORDER BY lastpid DESC,给 lastpid 单独建索引,或者建 (fid, lastpid) 联合索引。注意联合索引的最左前缀原则,别建了用不上。改完再用 SHOW STATUS LIKE 'Handler_read%' 看实际扫描行数有没有下降。

这六点不需要全部做完,挑两三个改下去就能看到明显变化。建议先从第一条和第五条开始,改动小、收益直接。改完用浏览器开发者工具的 Network 面板和 Performance 面板各录一次,对比请求数和 LCP 时间,心里有数再继续调。

评论0
最新打赏 共 1 次 · 1 金币
怪咖先生
怪咖先生 超管麟宫绮梦
管理员
+1金币
评论 · 0
还没有评论