performance-audit
Deep performance and optimization audit by senior WordPress developer
Install with Codex or Claude Copy this prompt, paste it into Codex, Claude, or another assistant, and let it review the skill page and install it for you.
Menu
Deep performance and optimization audit by senior WordPress developer
Install with Codex or Claude Copy this prompt, paste it into Codex, Claude, or another assistant, and let it review the skill page and install it for you.
Based on SOC occupation classification
Create a new Gutenberg block with scaffolding
Use when working with the WordPress Abilities API (wp_register_ability, wp_register_ability_category, /wp-json/wp-abilities/v1/*, @wordpress/abilities) including defining abilities, categories, meta, REST exposure, and permissions checks for clients.
Prepare plugin for WordPress.org deployment
Use when generating responses containing factual claims, API details, configuration specifics, version compatibility, or recalled knowledge that could be hallucinated - especially when not working directly from source code or command output
Use when executing implementation plans with independent tasks in the current session
Create a block extension to enhance core WordPress blocks
| name | performance-audit |
| description | Deep performance and optimization audit by senior WordPress developer |
| context | fork |
| agent | Explore |
| allowed-tools | Read, Glob, Grep, Bash(npm run *), Bash(find *), Bash(grep *), Bash(ls *) |
Act as a senior WordPress plugin developer with expertise in web performance optimization, Core Web Vitals, and React performance patterns. Conduct a comprehensive performance audit of the DesignSetGo WordPress plugin, identifying bottlenecks, optimization opportunities, and providing actionable fixes.
This is a DEEP PERFORMANCE AUDIT focusing exclusively on performance optimization across all layers: frontend, editor, database, asset loading, bundle size, rendering, and runtime performance.
JavaScript Bundles:
CSS Bundles:
Analysis Commands:
# Check build output sizes
ls -lh build/ | grep -E "\.js$|\.css$"
# Detailed bundle analysis
du -sh build/*.js build/*.css | sort -rh
# Gzipped sizes (production simulation)
find build/ -name "*.js" -o -name "*.css" | xargs -I {} sh -c 'echo "{}: $(gzip -c {} | wc -c) bytes gzipped"'
# Check for duplicate dependencies
grep -r "import.*from" src/ | grep -E "react|lodash|wp-" | sort | uniq -c | sort -rn
Optimization Targets:
Conditional Loading:
has_block() or has_blocks() used for conditional enqueuingAsset Dependencies:
Check Files:
includes/class-assets.php - Main asset loaderincludes/blocks/class-loader.php - Block registrationblock.json files - Asset declarationsCurrent Implementation Analysis:
// Check current loading strategy
grep -A 10 "wp_enqueue" includes/class-assets.php
// Check block asset registration
find src/blocks -name "block.json" -exec grep -H "script\|style" {} \;
// Find unconditional loading
grep -r "wp_enqueue_script\|wp_enqueue_style" includes/ | grep -v "is_admin\|has_block"
Best Practice Pattern:
// โ
GOOD - Conditional loading
public function enqueue_block_assets() {
if (!has_block('designsetgo/block-name')) {
return;
}
wp_enqueue_script('designsetgo-block-name');
}
// โ BAD - Always loads
public function enqueue_assets() {
wp_enqueue_script('designsetgo-all-blocks');
}
Runtime Performance:
DOM Manipulation:
Check Frontend Scripts:
# Find all frontend JavaScript
find src/ -name "view.js" -o -name "frontend.js"
# Check for performance anti-patterns
grep -r "setInterval\|setTimeout\|addEventListener" src/*/view.js src/*/frontend.js
# Check for DOM queries in loops
grep -A 5 "forEach\|for\|while" src/*/view.js | grep "querySelector\|getElementById"
Performance Patterns:
// โ
GOOD - Event delegation, cached selectors
const container = document.querySelector('[data-dsgo-tabs]');
container?.addEventListener('click', (e) => {
const tab = e.target.closest('[data-dsgo-tab]');
if (!tab) return;
handleTabClick(tab);
});
// โ BAD - Individual listeners, repeated queries
document.querySelectorAll('[data-dsgo-tab]').forEach(tab => {
tab.addEventListener('click', () => {
document.querySelector('[data-dsgo-tabs]').classList.add('active');
});
});
// โ
GOOD - Passive listeners, cleanup
const handleScroll = throttle(() => { /* ... */ }, 100);
window.addEventListener('scroll', handleScroll, { passive: true });
// Cleanup on unload
window.addEventListener('unload', () => {
window.removeEventListener('scroll', handleScroll);
});
Component Optimization:
useEffect for simple calculations (use useMemo instead)useMemouseCallbackAttribute Updates:
setAttributes in loopsCheck Editor Performance:
# Find useEffect usage (often unnecessary)
grep -r "useEffect" src/blocks/*/edit.js -A 3
# Find missing memoization
grep -r "const.*=" src/blocks/*/edit.js | grep -v "useMemo\|useCallback\|useState\|useSelect"
# Check for expensive operations
grep -r "map\|filter\|reduce\|sort" src/blocks/*/edit.js
Performance Patterns:
// โ BAD - useEffect for simple calculation
useEffect(() => {
setComputedValue(width * height);
}, [width, height]);
// โ
GOOD - useMemo for calculation
const computedValue = useMemo(() => width * height, [width, height]);
// โ BAD - Inline function causes re-renders
<Button onClick={() => setAttributes({ value: 'new' })}>
// โ
GOOD - Memoized callback
const handleClick = useCallback(() => {
setAttributes({ value: 'new' });
}, []);
<Button onClick={handleClick}>
// โ BAD - Setting attributes in loop
items.forEach(item => {
setAttributes({ [item.key]: item.value });
});
// โ
GOOD - Batch updates
const updates = items.reduce((acc, item) => ({
...acc,
[item.key]: item.value
}), {});
setAttributes(updates);
Selector Performance:
:where() for plugin styles).wp-block-designsetgo-*)*).a .b .c .d)!important (except accessibility overrides)CSS Optimization:
Check CSS Quality:
# Find high-specificity selectors
grep -r "\..*\..*\..*\." src/blocks/*/style.scss
# Find !important usage
grep -r "!important" src/ --include="*.scss" --include="*.css"
# Check for universal selectors
grep -r "\* {" src/ --include="*.scss"
# Find duplicate rules
cat build/style-index.css | grep -E "^\.[a-z-]+ \{" | sort | uniq -d
Performance Patterns:
// โ
GOOD - Low specificity with :where()
:where(.wp-block-designsetgo-stack) {
display: flex;
}
// โ BAD - High specificity
.wp-block-designsetgo-stack.custom-class.is-variant {
display: flex;
}
// โ
GOOD - Scoped to block
.wp-block-designsetgo-stack {
.stack__item {
flex: 1;
}
}
// โ BAD - Global scope
.stack__item {
flex: 1;
}
// โ
GOOD - Performance optimization
.wp-block-designsetgo-gallery {
contain: layout style paint;
content-visibility: auto;
}
Database Queries:
PHP Optimization:
Check PHP Performance:
# Find database queries
grep -r "wpdb\|get_option\|update_option\|get_transient" includes/ --include="*.php"
# Check for queries in loops
grep -A 10 "foreach\|for\|while" includes/ | grep "wpdb\|get_"
# Find autoloaded options
grep -r "add_option\|update_option" includes/ | grep -v "false"
Performance Patterns:
// โ BAD - Query in loop
foreach ($blocks as $block) {
$meta = get_post_meta($block->ID);
}
// โ
GOOD - Batch query
update_meta_cache('post', array_column($blocks, 'ID'));
foreach ($blocks as $block) {
$meta = get_post_meta($block->ID); // Cached
}
// โ BAD - No caching
$patterns = $this->get_all_patterns(); // Expensive
// โ
GOOD - Transient caching
$patterns = get_transient('dsg_patterns');
if (false === $patterns) {
$patterns = $this->get_all_patterns();
set_transient('dsg_patterns', $patterns, HOUR_IN_SECONDS);
}
Image Handling:
loading="lazy")Video Handling:
Check Media Usage:
# Find image tags
grep -r "<img" src/blocks/*/save.js
# Check for lazy loading
grep -r "loading=" src/blocks/*/save.js
# Find video usage
grep -r "<video" src/blocks/*/save.js
Build Configuration:
Check Build Config:
// Review webpack.config.js
- mode: 'production'
- optimization.minimize: true
- optimization.splitChunks: configured
- externals: WordPress dependencies
- devtool: false (production)
Optimization Opportunities:
// Check for large dependencies
npm list --depth=0 --long
// Analyze bundle
npm run build -- --analyze
// Check for unused dependencies
npm install -g depcheck
depcheck
Largest Contentful Paint (LCP):
Cumulative Layout Shift (CLS):
First Input Delay (FID) / INP:
Total Blocking Time (TBT):
Testing Commands:
# Lighthouse CI (if configured)
npm run test:performance
# Measure bundle impact
ls -lh build/*.js | awk '{sum+=$5} END {print "Total JS:", sum/1024, "KB"}'
# Check for render-blocking resources
grep -r "enqueue_script\|enqueue_style" includes/ | grep -v "defer\|async"
Memory Leaks:
Resource Cleanup:
Check for Leaks:
# Find event listeners without cleanup
grep -A 10 "addEventListener" src/ | grep -B 10 -v "removeEventListener"
# Find timers without cleanup
grep -A 10 "setInterval\|setTimeout" src/ | grep -B 10 -v "clearInterval\|clearTimeout"
# Find observers without cleanup
grep -A 10 "Observer" src/ | grep -B 10 -v "disconnect\|unobserve"
# Build the plugin
npm run build
# Check build output
ls -lh build/
# Measure total bundle size
find build/ -type f \( -name "*.js" -o -name "*.css" \) -exec ls -lh {} \; | awk '{total+=$5} END {print "Total:", total/1024/1024, "MB"}'
Generate a comprehensive PERFORMANCE-AUDIT.md file with this structure:
# DesignSetGo WordPress Plugin - Performance & Optimization Audit
**Audit Date:** YYYY-MM-DD
**Plugin Version:** X.X.X
**Auditor Role:** Senior WordPress Performance Engineer
**Environment:** WordPress X.X, PHP X.X
## Executive Summary
### Overall Performance Grade
[A+, A, B+, B, C+, C, D, F]
### Performance Impact Score
[Excellent | Good | Fair | Poor | Critical]
### Key Metrics
- **Total Bundle Size:** XXX KB (gzipped: XXX KB)
- **Largest Block Bundle:** XXX KB
- **Frontend JS:** XXX KB (Target: < 50KB)
- **Critical Issues:** XX
- **Optimization Opportunities:** XX
- **Estimated Performance Gain:** XX%
### Quick Wins (High Impact, Low Effort)
1. [Optimization that provides biggest benefit for least work]
2. [Optimization that provides biggest benefit for least work]
3. [Optimization that provides biggest benefit for least work]
## ๐ด CRITICAL PERFORMANCE ISSUES
### 1. [Issue Title]
**Impact:** [Blocks LCP | Increases TBT | Causes Memory Leak | etc.]
**Files Affected:** `path/to/file.js:123`, `path/to/file.php:456`
**Problem:**
[Clear description of performance issue and measurable impact]
**Current Measurement:**
- Metric before: XXX ms / XX KB
- Target: XXX ms / XX KB
- Impact on users: [Description]
**Current Code:**
```javascript
// Problematic code
Optimized Code:
// Performance-optimized code with explanation
Performance Gain:
Implementation Time: [15 min | 1 hour | 4 hours | 1 day] Priority: Critical - Fix immediately
[Same detailed format as critical issues]
[List opportunities with size savings]
[List opportunities with specificity/render improvements]
[List unnecessary re-renders, missing memoization]
[Refactoring for better maintainability]
[Ideas for future consideration]
Block Name | JS (raw) | JS (gzip) | CSS (raw) | CSS (gzip) | Status
--------------------|----------|-----------|-----------|------------|--------
flex | 15.2 KB | 4.8 KB | 3.1 KB | 1.2 KB | โ
Good
grid | 32.5 KB | 12.3 KB | 8.2 KB | 3.1 KB | โ ๏ธ Large
accordion | 8.1 KB | 2.9 KB | 2.4 KB | 0.9 KB | โ
Excellent
--------------------|----------|-----------|-----------|------------|--------
TOTAL | 180 KB | 65 KB | 42 KB | 18 KB | โ ๏ธ Review
Scenario | Assets Loaded | Total Size | Status
----------------------------------|---------------|------------|--------
Empty page (no blocks) | 0 | 0 KB | โ
Perfect
Page with 1 block | 2 files | 15 KB | โ
Good
Page with 5 different blocks | 8 files | 85 KB | โ ๏ธ Review
Page with 10+ blocks | 12 files | 150 KB | ๐ด High
Metric | Without Plugin | With Plugin | Impact | Target | Status
-------|----------------|-------------|--------|--------|--------
LCP | 1.2s | 1.8s | +0.6s | <2.5s | โ
Pass
FID | 45ms | 120ms | +75ms | <100ms | โ ๏ธ Warn
CLS | 0.02 | 0.05 | +0.03 | <0.1 | โ
Pass
TBT | 150ms | 380ms | +230ms | <300ms | ๐ด Fail
Test Scenario | Memory Used | Memory Leaks | Status
----------------------------|-------------|--------------|--------
10 blocks in editor | 85 MB | None | โ
Good
50 blocks in editor | 420 MB | None | โ ๏ธ High
Editor after 10min use | 180 MB | 15 MB growth | ๐ด Leak
Frontend with 20 blocks | 25 MB | None | โ
Good
Goal: Fix performance blockers preventing production deployment Estimated Impact: 40% performance improvement
Success Metrics:
Goal: Major performance improvements with reasonable effort Estimated Impact: 25% additional improvement
Success Metrics:
Goal: Fine-tune for optimal performance Estimated Impact: 10% additional improvement
Success Metrics:
Goal: Maintain performance over time
# Add to package.json
"scripts": {
"analyze": "webpack-bundle-analyzer build/stats.json",
"performance": "lighthouse https://example.com",
"size-limit": "size-limit"
}
// .size-limit.json
[
{
"path": "build/index.js",
"limit": "100 KB"
},
{
"path": "build/style-index.css",
"limit": "50 KB"
}
]
npm run build successfullyEnd of Performance Audit
## Execution Strategy
### 1. **Initial Analysis (15 minutes)**
- Build the plugin and analyze output
- Review webpack configuration
- Check bundle sizes
- Identify largest files
### 2. **Bundle Analysis (30 minutes)**
- Analyze each block bundle
- Check for duplicate dependencies
- Identify optimization opportunities
- Test tree shaking effectiveness
### 3. **Asset Loading Review (20 minutes)**
- Review asset loading strategy
- Check conditional loading
- Identify unnecessary global assets
- Test asset dependencies
### 4. **Frontend Performance (30 minutes)**
- Review all frontend JavaScript
- Check for memory leaks
- Analyze event listener patterns
- Test runtime performance
### 5. **Editor Performance (30 minutes)**
- Review React components
- Check for unnecessary re-renders
- Identify missing memoization
- Test with multiple blocks
### 6. **CSS Performance (20 minutes)**
- Analyze CSS specificity
- Check for duplicate rules
- Review selector patterns
- Identify optimization opportunities
### 7. **Database & PHP (20 minutes)**
- Review database queries
- Check caching implementation
- Analyze PHP performance
- Identify bottlenecks
### 8. **Core Web Vitals (30 minutes)**
- Run Lighthouse audit
- Test on slow connection
- Measure impact on LCP, FID, CLS
- Identify render-blocking resources
### 9. **Generate Report (45 minutes)**
- Compile all findings
- Prioritize by impact and effort
- Write detailed fixes with code examples
- Create optimization roadmap
## Analysis Commands Reference
```bash
# Bundle size analysis
npm run build
ls -lh build/ | grep -E "\.js$|\.css$"
du -h build/ | sort -rh | head -20
# Gzipped sizes
find build/ -name "*.js" -exec sh -c 'echo "{}: $(gzip -c {} | wc -c) bytes"' \;
# Dependency analysis
npm list --depth=0
grep -r "import.*from" src/ | grep -oP "from ['\"].*?['\"]" | sort | uniq -c | sort -rn
# Frontend JavaScript
find src/ -name "view.js" -o -name "frontend.js"
grep -r "addEventListener\|querySelector" src/*/view.js
# React performance
grep -r "useEffect\|useMemo\|useCallback" src/blocks/*/edit.js
# CSS analysis
grep -r "!important" src/ --include="*.scss"
cat build/style-index.css | wc -l
# Database queries
grep -r "wpdb\|get_option\|get_transient" includes/ --include="*.php"
# Memory leaks
grep -A 10 "addEventListener" src/ | grep -v "removeEventListener"
grep -A 10 "setInterval\|setTimeout" src/ | grep -v "clear"
A successful performance audit should:
DELIVER VALUE: The audit should make the plugin measurably faster with clear steps to achieve it.