EP02. "wp-performance-review 性能审查"
🔒 登录后可标记已读- 网站一到大促/直播/上热搜就开始超时、500、数据库锁死,回头翻代码常常发现就是
posts_per_page => -1、循环里查数据库这几个老毛病——wp-performance-review专门抓这些 - 这是
jorgerosal/wordpress-skills这个开源 skill 包里跟wp-security-review平级的另一个技能,专注性能反模式,不查安全问题 - 套路是「先抓会导致 OOM/超时/500 的 CRITICAL,再抓拖慢但不致命的 WARNING,最后才是锦上添花的 INFO」,报告一样带行号、严重度
- 前置知识:先看过 Overview 系列的「Claude Code 是什么与新手上手」「进阶功能:Skills、Plugins 与 Routines」两篇,再看过 EP01 「wp-security-review 安全审查」了解这一整套 skill 的调用方式最好
重点内容
这个 Skill 是做什么的
wp-performance-review 系统性扫 WordPress 主题/插件/自定义代码里的性能反模式:数据库查询写法、hook 里跑了太重的逻辑、页面加载时写数据库、object cache 和 transient 用得对不对、AJAX/HTTP 请求会不会变成轮询炸弹、模板里有没有 N+1 查询、资源加载策略、WP-Cron 有没有写坏。
适合用在:
- Review WordPress 主题/插件的 PR 或代码
- 有人反馈页面慢、超时、500 错误
- 大促/发布/爆红事件前的性能审计
- 优化
WP_Query或数据库操作 - 排查内存耗尽(OOM)或数据库锁
不适合用在:
- 纯安全审查(交给
wp-security-review) - Gutenberg block 开发模式审查(交给
wp-block-development) - 跟 WordPress 无关的通用 PHP 代码审查
- 不涉及 WordPress 性能行为的产品/UX 评审
触发方式
| 方式 | 写法 | 说明 |
|---|---|---|
| 斜线指令(完整版) | /wp-perf-review [path] | 完整审查,按严重度分组输出 |
| 斜线指令(快速版) | /wp-perf [path] | 只抓关键反模式,适合日常小改动后快速过一遍 |
| 自然语言 | 「审查这段代码的性能问题」「why is this WordPress site slow」 | Claude 判断意图符合就自动触发 |
📌 path 留空扫整个项目,也可以指到具体文件夹。
按文件类型抓的坑
| 文件类型 | 主要检查项 |
|---|---|
| 插件/主题 PHP 文件 | query_posts()(CRITICAL,破坏主查询)、posts_per_page/numberposts 等于 -1(无边界查询)、session_start()(绕过页面缓存)、init/wp_loaded 里跑重逻辑、非后台环境里 update_option()/add_option()(页面加载时写库) |
WP_Query / 数据库操作 | 缺 posts_per_page 参数、meta_query 用 value 比较(未建索引全表扫)、LIKE '%term%' 前置通配符(全表扫)、大量 post__not_in 配分页/排序(SQL 变贵)、不分页却没设 no_found_rows => true |
| AJAX handler / REST endpoint | 读操作用了 POST(绕过缓存)、setInterval/轮询模式(CRITICAL,等于自己 DDoS 自己)、缺 nonce 验证 |
| 模板文件 | loop 里直接查数据库/未缓存的 get_post_meta()/远程请求(N+1 风险)、loop 里的 wp_remote_get()(阻塞渲染) |
| Transient & Options | set_transient() 用动态 key(例如 user_{$id},没有 object cache 时撑爆 wp_options 表)、给频繁变动的数据设 transient(失去缓存意义) |
| WP-Cron | 缺 DISABLE_WP_CRON 常量、cron 回调里跑全量循环(阻塞整个 cron 队列)、wp_schedule_event() 没检查是否已排程(重复排程) |
不同 hosting 环境的判断标准不一样
| 环境 | 审查时要注意 |
|---|---|
| Managed WordPress(WP Engine、Pantheon、Pressable、VIP 等) | 通常自带 object cache;VIP 有专属 helper 函数(如 wpcom_vip_*),先查官方文档推荐写法 |
| 自建主机 / 一般虚拟主机 | 常见函数要自己包一层 object cache,考虑上 Redis/Memcached |
| 共享主机 | 资源有限,无边界查询/外部 HTTP 请求的风险更高,往往连持久化 object cache 都没有 |
实操示例
// ❌ CRITICAL:无边界查询,撑爆内存
'posts_per_page' => -1
// ✅ GOOD:设合理上限,不分页就跳过 count
'posts_per_page' => 100,
'no_found_rows' => true,
// ❌ CRITICAL:永远不要用 query_posts(),会破坏分页和条件判断
query_posts( 'cat=1' );
// ✅ GOOD:用 WP_Query,或用 pre_get_posts 改主查询
$query = new WP_Query( array( 'cat' => 1 ) );
add_action( 'pre_get_posts', function( $query ) {
if ( $query->is_main_query() && ! is_admin() ) {
$query->set( 'cat', 1 );
}
} );
// ❌ CRITICAL:插件在前台开 PHP session,整站页面缓存直接失效
session_start(); // 排查插件时一定要 grep 这个
// ❌ WARNING:每次页面加载都写一次数据库
add_action( 'wp_head', 'prefix_bad_tracking' );
function prefix_bad_tracking() {
update_option( 'last_visit', time() );
}
// ✅ GOOD:先写进 object cache 缓冲区,靠 cron 定期落库
add_action( 'shutdown', function() {
wp_cache_incr( 'page_views_buffer', 1, 'counters' );
} );
// ❌ CRITICAL:cron 回调里一次性处理全部用户,5 万用户等于跑几小时,阻塞整个 cron 队列
add_action( 'my_daily_sync', function() {
foreach ( get_users() as $user ) {
sync_user_data( $user );
}
} );
// ✅ GOOD:分批处理,处理完一批就重新排程下一批
add_action( 'my_batch_sync', function() {
$offset = (int) get_option( 'sync_offset', 0 );
$users = get_users( array( 'number' => 100, 'offset' => $offset ) );
if ( empty( $users ) ) {
delete_option( 'sync_offset' );
return;
}
foreach ( $users as $user ) {
sync_user_data( $user );
}
update_option( 'sync_offset', $offset + 100 );
wp_schedule_single_event( time() + 60, 'my_batch_sync' );
} );
怎么安装
这个 skill 是 wordpress-skills 这个开源仓库(jorgerosal/wordpress-skills)打包的 18 个技能之一,安装一次,18 个技能一起到位,不用逐个装:
Claude Code:
| 方式 | 指令 | 适用场景 |
|---|---|---|
| 装进单个项目(推荐) | git submodule add https://github.com/jorgerosal/wordpress-skills.git .claude/plugins/wordpress-skills | 只想在这个项目用,团队成员 clone 项目就一起有 |
| 装到自己账号 | git clone https://github.com/jorgerosal/wordpress-skills.git ~/.claude/plugins/wordpress-skills | 所有项目都能用 |
| 只装这一个 skill | cp -r claude-skills/wp-performance-review ~/.claude/skills/ | 只想要性能审查这一个功能,不要其他 17 个 |
装完重启 Claude Code,进到一个 WordPress 项目里跑 /wordpress-skills:wp-perf-review 验证有没有装成功(用 marketplace/submodule 方式装的话,指令前面会带插件命名空间 wordpress-skills:;用「只装这一个 skill」的方式则不带命名空间,直接 /wp-perf-review)。
Claude Desktop / claude.ai: 走 Settings → Capabilities → Skills,上传技能文件夹(把 claude-skills/wp-performance-review 这个文件夹打包上传,里面要包含 SKILL.md)——跟 Claude Code 的 git submodule/marketplace 安装方式不同,Desktop 端是手动上传 UI,装好之后同样能用自然语言或 slash 指令触发。
常见错误
- ❌ 后台专用代码里的
posts_per_page => -1也被当成 CRITICAL 打回去——后台查询不用面对公开流量规模,风险要按场景降级 - ❌ 漏掉插件里藏得很深的
session_start()——这一行足以让整站缓存失效,审查时一定要全项目 grep 一遍,不能只看当前改动的文件 - ❌ 非分页查询没设
no_found_rows被标成 WARNING——这只是个小优化,应该标 INFO,别夸大严重度 - ❌ 共享主机场景下建议直接上 object cache——很多共享主机根本没有持久化缓存,先确认 hosting 环境再给建议
- ❌ 只看 PHP 文件,漏掉前端
.js里的轮询模式——setInterval配fetch/AJAX 等于自己对自己 DDoS,这类文件也要审 - 💡 判断严重度前先搞清楚运行环境(managed hosting / 自建 / 共享主机),同一个反模式在不同环境风险不一样
Sources
官方文档:
- wordpress-skills(GitHub 仓库)— https://github.com/jorgerosal/wordpress-skills
- wp-performance-review SKILL.md — https://github.com/jorgerosal/wordpress-skills/blob/main/claude-skills/wp-performance-review/SKILL.md