Client calls. Their site is "just slow." No other details.
Here's the process I've refined over years of WordPress maintenance for diagnosing performance issues fast - from first look to prioritized action list in about 30 minutes.
Step 1: Baseline measurements (5 minutes)
Before touching anything, document where you're starting.
Run every test 3 times and average:
- Google PageSpeed Insights (mobile + desktop): pagespeed.web.dev
- GTmetrix: note TTFB, total page size, total requests
- Google Search Console: Core Web Vitals report (if you have access)
The numbers that matter most:
| Metric | Target | What it affects |
|---|---|---|
| LCP | < 2.5s | Largest Contentful Paint - Google ranking |
| TTFB | < 800ms | Server response - often hosting problem |
| Page size | < 3MB | Bandwidth - especially mobile |
| Mobile score | > 70 | Google uses mobile-first indexing |
Write these down. You can't prove improvement without a baseline.
Step 2: Server response time tells you 80% of the story
TTFB (Time to First Byte) is the most revealing single metric.
# Quick TTFB check from command line
curl -o /dev/null -s -w "TTFB: %{time_starttransfer}s\n" https://example.com
Under 200ms: Server is fast, look elsewhere
200ms-800ms: Acceptable, worth improving
Over 800ms: Server or caching problem - fix this first before anything else
If TTFB is high, check:
- PHP version - PHP 8.1+ is 2-3x faster than 7.4 for WordPress. Check in WP Admin ? Tools ? Site Health
-
Page cache - Is there any caching at all? Check response headers:
curl -I https://example.com | grep -i cache - Hosting tier - Shared hosting with too many neighbors causes slow TTFB regardless of optimization
Step 3: Images are almost always the main culprit
Open GTmetrix ? Waterfall tab ? filter by "Image" ? sort by size.
Nine times out of ten, I find:
- Hero images at 2-4MB (should be 100-300KB)
- Images served at 3000px width but displayed at 800px
- JPEG format instead of WebP (30-50% larger)
- No lazy loading on below-fold images
Quick diagnosis:
// Run in browser console to find oversized images
document.querySelectorAll('img').forEach(img => {
const rendered = img.getBoundingClientRect();
const natural = { w: img.naturalWidth, h: img.naturalHeight };
const waste = ((natural.w * natural.h) / (rendered.width * rendered.height)).toFixed(1);
if (waste > 4) console.log(`Oversized: ${img.src.split('/').pop()} - ${waste}x larger than needed`);
});
Fix priority:
- Compress existing images (ShortPixel, free tier = 100 images/month)
- Enable WebP conversion going forward
- Set explicit width/height on images (prevents layout shift)
- Don't lazy-load above-fold images (hurts LCP)
Step 4: Caching check
Page caching is the single highest-impact fix for most WordPress sites.
Test if caching is active:
curl -I https://example.com | grep -i "x-cache\|cf-cache\|cache-control"
If you see X-Cache: HIT or CF-Cache-Status: HIT - caching is working.
If you see nothing or Cache-Control: no-cache - no page cache.
Without caching: Every visitor triggers PHP + database. 500ms-3s server time.
With caching: Pre-built HTML served directly. 50-200ms.
Best free options by hosting type:
- Shared hosting (Apache): W3 Total Cache or WP Super Cache
- LiteSpeed servers: LiteSpeed Cache (dramatically better than W3TC)
- WP Engine / Kinsta / SiteGround: Built-in server cache - just make sure it's not disabled
Step 5: JavaScript bloat
Open Chrome DevTools ? Network ? filter JS ? reload ? sort by size.
Look for:
- Files over 100KB (especially ones you don't recognize)
- Scripts loading on pages where they're not needed (contact form plugin loading on every page)
- Multiple jQuery versions (yes, this happens)
Find render-blocking scripts:
PageSpeed Insights ? "Eliminate render-blocking resources" ? shows you exactly which files.
Fix options:
- Defer non-critical scripts:
<script src="..." defer></script> - Use Asset CleanUp plugin to disable specific scripts on specific page types
- Remove plugins you're not using (every plugin = more JS)
Step 6: Database audit
Runs slow even with caching? Look at the database.
Install Query Monitor plugin temporarily and load a few pages. Check:
- Queries tab: anything over 50ms is suspicious
- Number of queries: over 100 per page is high
Also check directly:
-- Autoloaded data (should be under 1MB)
SELECT SUM(LENGTH(option_value))/1024/1024 as mb
FROM wp_options
WHERE autoload = 'yes';
-- Post revisions (often thousands on active sites)
SELECT COUNT(*) FROM wp_posts
WHERE post_type = 'revision';
Quick wins:
// Add to wp-config.php - limit revisions going forward
define('WP_POST_REVISIONS', 5);
Then use WP-Optimize to clean up existing bloat.
Step 7: The things people forget
Google Fonts: Every Google Fonts family = external DNS lookup + connection. For a site with 3 font families loaded from fonts.googleapis.com, that's 3 extra connections before the page can render.
Fix: Host fonts locally with the OMGF plugin. Free, 10-minute setup.
Font display: Text invisible while font loads? Add font-display: swap to @font-face declarations. Prevents invisible text from hurting LCP.
Third-party scripts: Chat widgets, analytics tags, social share buttons - each one adds DNS lookup + connection time. Audit them. Do you actually need all of them?
My 30-minute flow
0-5min: Baseline measurements (PageSpeed + GTmetrix)
5-10min: TTFB check ? hosting/caching decision
10-15min: Image audit via Waterfall
15-20min: Cache headers check + caching plugin status
20-25min: JS bloat + render-blocking resources
25-30min: Database quick check + fonts
Result: Prioritized list of fixes with estimated impact for each.
The report I send clients
After the audit, I send a one-page report: current scores, issues by priority (critical / important / nice-to-have), what I fixed, what I recommend, and projected improvement.
I've put together the full checklist, implementation guides, and the client report template in a kit:
WordPress Speed & Performance Audit Kit ? - use SPEED for 26% off.
Or just use the checklist above on your next slow site.
What's the most common performance issue you find on client WordPress sites? Drop it in the comments.
More in this series: WordPress Agency Toolkit
- I automated WordPress maintenance across 8 sites
- How I land WordPress maintenance clients with cold email
- WordPress site running slow? 30-minute diagnosis checklist
- The WordPress maintenance business: real numbers and pricing
- WooCommerce maintenance: 8 checks that keep payments alive
- MainWP vs ManageWP vs custom scripts
- WordPress security: 10-minute monthly checklist
All tools and templates: devautomation.gumroad.com
Top comments (0)