$npx -y skills add elvismdev/claude-wordpress-skills --skill wp-performance-reviewWordPress performance code review and optimization analysis. Use when reviewing WordPress PHP code for performance issues, auditing themes/plugins for scalability, optimizing WP_Query, analyzing caching strategies, checking code before launch, or detecting anti-patterns, or when
| 1 | # WordPress Performance Review Skill |
| 2 | |
| 3 | ## Overview |
| 4 | |
| 5 | Systematic performance code review for WordPress themes, plugins, and custom code. **Core principle:** Scan critical issues first (OOM, unbounded queries, cache bypass), then warnings, then optimizations. Report with line numbers and severity levels. |
| 6 | |
| 7 | ## When to Use |
| 8 | |
| 9 | **Use when:** |
| 10 | - Reviewing PR/code for WordPress theme or plugin |
| 11 | - User reports slow page loads, timeouts, or 500 errors |
| 12 | - Auditing before high-traffic event (launch, sale, viral moment) |
| 13 | - Optimizing WP_Query or database operations |
| 14 | - Investigating memory exhaustion or DB locks |
| 15 | |
| 16 | **Don't use for:** |
| 17 | - Security-only audits (use wp-security-review when available) |
| 18 | - Gutenberg block development patterns (use wp-gutenberg-blocks when available) |
| 19 | - General PHP code review not specific to WordPress |
| 20 | |
| 21 | ## Code Review Workflow |
| 22 | |
| 23 | 1. **Identify file type** and apply relevant checks below |
| 24 | 2. **Scan for critical patterns first** (OOM, unbounded queries, cache bypass) |
| 25 | 3. **Check warnings** (inefficient but not catastrophic) |
| 26 | 4. **Note optimizations** (nice-to-have improvements) |
| 27 | 5. **Report with line numbers** using output format below |
| 28 | |
| 29 | ## File-Type Specific Checks |
| 30 | |
| 31 | ### Plugin/Theme PHP Files (`functions.php`, `plugin.php`, `*.php`) |
| 32 | Scan for: |
| 33 | - `query_posts()` → CRITICAL: Never use - breaks main query |
| 34 | - `posts_per_page.*-1` or `numberposts.*-1` → CRITICAL: Unbounded query |
| 35 | - `session_start()` → CRITICAL: Bypasses page cache |
| 36 | - `add_action.*init.*` or `add_action.*wp_loaded` → Check if expensive code runs every request |
| 37 | - `update_option` or `add_option` in non-admin context → WARNING: DB writes on page load |
| 38 | - `wp_remote_get` or `wp_remote_post` without caching → WARNING: Blocking HTTP |
| 39 | |
| 40 | ### WP_Query / Database Code |
| 41 | Scan for: |
| 42 | - Missing `posts_per_page` argument → WARNING: Defaults to blog setting |
| 43 | - `'meta_query'` with `'value'` comparisons → WARNING: Unindexed column scan |
| 44 | - `post__not_in` with large arrays → WARNING: Slow exclusion |
| 45 | - `LIKE '%term%'` (leading wildcard) → WARNING: Full table scan |
| 46 | - Missing `no_found_rows => true` when not paginating → INFO: Unnecessary count |
| 47 | |
| 48 | ### AJAX Handlers (`wp_ajax_*`, REST endpoints) |
| 49 | Scan for: |
| 50 | - `admin-ajax.php` usage → INFO: Consider REST API instead |
| 51 | - POST method for read operations → WARNING: Bypasses cache |
| 52 | - `setInterval` or polling patterns → CRITICAL: Self-DDoS risk |
| 53 | - Missing nonce verification → Security issue (not performance, but flag it) |
| 54 | |
| 55 | ### Template Files (`*.php` in theme) |
| 56 | Scan for: |
| 57 | - `get_template_part` in loops → WARNING: Consider caching output |
| 58 | - Database queries inside loops (N+1) → CRITICAL: Query multiplication |
| 59 | - `wp_remote_get` in templates → WARNING: Blocks rendering |
| 60 | |
| 61 | ### JavaScript Files |
| 62 | Scan for: |
| 63 | - `$.post(` for read operations → WARNING: Use GET for cacheability |
| 64 | - `setInterval.*fetch\|ajax` → CRITICAL: Polling pattern |
| 65 | - `import _ from 'lodash'` → WARNING: Full library import bloats bundle |
| 66 | - Inline `<script>` making AJAX calls on load → Check necessity |
| 67 | |
| 68 | ### Block Editor / Gutenberg Files (`block.json`, `*.js` in blocks/) |
| 69 | Scan for: |
| 70 | - Many `registerBlockStyle()` calls → WARNING: Each creates preview iframe |
| 71 | - `wp_kses_post($content)` in render callbacks → WARNING: Breaks InnerBlocks |
| 72 | - Static blocks without `render_callback` → INFO: Consider dynamic for maintainability |
| 73 | |
| 74 | ### Asset Registration (`functions.php`, `*.php`) |
| 75 | Scan for: |
| 76 | - `wp_enqueue_script` without version → INFO: Cache busting issues |
| 77 | - `wp_enqueue_script` without `defer`/`async` strategy → INFO: Blocks rendering |
| 78 | - Missing `THEME_VERSION` constant → INFO: Version management |
| 79 | - `wp_enqueue_script` without conditional check → WARNING: Assets load globally when only needed on specific pages |
| 80 | |
| 81 | ### Transients & Options |
| 82 | Scan for: |
| 83 | - `set_transient` with dynamic keys (e.g., `user_{$id}`) → WARNING: Table bloat without object cache |
| 84 | - `set_transient` for frequently-changing data → WARNING: Defeats caching purpose |
| 85 | - Large data in transients on shared hosting → WARNING: DB bloat without object cache |
| 86 | |
| 87 | ### WP-Cron |
| 88 | Scan for: |
| 89 | - Missing `DISABLE_WP_CRON` constant → INFO: Cron runs on page requests |
| 90 | - Long-running cron callbacks (loops over all users/posts) → CRITICAL: Blocks cron queue |
| 91 | - `wp_schedule_event` without checking if already scheduled → WARNING: Duplicate schedules |
| 92 | |
| 93 | ## Search Patterns for Quick Detection |
| 94 | |
| 95 | ```bash |
| 96 | # Critical issues - scan these first |
| 97 | grep -rn "posts_per_page.*-1\|numberposts.*-1" . |
| 98 | gre |