Start with measurement, not tools
Before touching anything, measure. Open Google PageSpeed Insights, run your URL against both mobile and desktop, and read the diagnostics — not just the score. The score is a summary. The diagnostics tell you what to fix.
The three Core Web Vitals you need to understand are Largest Contentful Paint (LCP), Interaction to Next Paint (INP), and Cumulative Layout Shift (CLS). Google uses all three as ranking signals. LCP is the most important for most WordPress sites: it measures how quickly the largest visible element — usually a hero image or heading — loads.
A good LCP is under 2.5 seconds. Most WordPress sites I audit come in between 4 and 8 seconds on mobile. The gap between 4 seconds and 2.4 seconds is not a caching problem. It is usually three or four separate architectural problems compounding each other.
Run your test from a mobile connection, not desktop. Google primarily uses mobile performance for ranking. Your desktop score is vanity — your mobile score is the one that affects your search visibility.
LCP Thresholds — Core Web Vitals
Most WordPress sites I audit arrive at 4–8 seconds (Poor)
The plugin audit: where most time is lost
The average WordPress site has 23 active plugins. Each plugin adds PHP execution time, database queries, and often frontend JavaScript. The cumulative effect is the single largest contributor to slow WordPress load times.
The audit process is straightforward. Install Query Monitor (free). Load your homepage. Open the Query Monitor panel and look at: total database queries, slowest queries, and which plugins triggered them. You will almost always find two or three plugins generating 60–80% of the database load.
Common offenders: WooCommerce combined with poorly configured product filtering plugins that run unindexed queries on every page load; SEO plugins that regenerate computed data on every request rather than caching it; security plugins that check every file on every page load.
The solution is not always to remove the plugin. It is to understand what work it is doing and whether that work needs to happen on every request. A sitemap regeneration should happen on a schedule, not on every page load. A security scan should run daily, not on every visitor.
Caching: the right architecture
Caching is the single most impactful change you can make to a slow WordPress site. But "install a caching plugin" is not a caching strategy — it is a first step.
There are three levels of caching that matter for WordPress: object caching (database query results), page caching (fully rendered HTML), and browser caching (static assets). Most sites only implement page caching and wonder why performance is still inconsistent.
Object caching requires Redis or Memcached — persistent, in-memory storage that keeps expensive database query results available across requests. Without it, even a page-cached WordPress site hits the database repeatedly for logged-in users, WooCommerce cart data, and dynamic sidebar widgets.
The right caching architecture depends on your hosting environment. On shared hosting, page caching with W3 Total Cache or WP Super Cache is the ceiling. On VPS or managed WordPress hosting (Kinsta, WP Engine, Pressidium), Redis object caching is available and should be active on any site with WooCommerce or membership functionality.
One common mistake: enabling full-page caching on a WooCommerce store without correctly excluding dynamic pages. Cart, checkout, account, and any page with personalised content must bypass the page cache entirely. Misconfigured caching causes more problems than no caching.
Images: the problem is not compression
Most image optimisation guides focus on compression. Compression matters, but it is the third problem, not the first.
The first problem is format. Any WordPress site still serving JPEG and PNG as primary formats is leaving a significant performance gain on the table. WebP provides 25–35% smaller file sizes at equivalent visual quality. AVIF provides 50% smaller sizes. Both are supported by all major browsers. Both should be your default output formats.
The second problem is sizing. A hero image rendered at 1200px wide does not need to be a 3000px file. WordPress generates multiple image sizes on upload, but many themes and page builders do not use the correct size for each context. The result is mobile users downloading 4MB images to display at 375px width.
The third problem is lazy loading. Every image below the fold should carry loading="lazy". Every image above the fold — particularly the LCP image — should carry fetchpriority="high" and should not be lazy-loaded. This distinction matters: lazy-loading your hero image will reliably destroy your LCP score.
Use Imagify or ShortPixel for compression and format conversion. Use the native WordPress srcset system for responsive sizing. Add fetchpriority="high" to your hero image manually if your theme or builder does not do it automatically.
JavaScript and render-blocking resources
A JavaScript file in the <head> of your HTML stops the browser from rendering anything until the file has been downloaded, parsed, and executed. This is render-blocking, and it is the single most common cause of poor FCP (First Contentful Paint) on WordPress sites.
The fix is loading order. Non-critical scripts should be deferred (loaded after HTML parsing) or async (loaded in parallel, executed when ready). Critical scripts — those required to render the initial view — should be inlined or preloaded.
Most WordPress plugins load their JavaScript in the head without checking whether it is required on the current page. A slider plugin loads its script on every page, including pages with no sliders. A form plugin loads its script everywhere, including pages with no forms. This is endemic to the WordPress plugin ecosystem and requires manual intervention.
Use the Asset CleanUp Pro plugin to disable scripts and styles on a per-page basis. Start with your checkout page: load only what is required for the checkout flow. The performance improvement on a WooCommerce checkout stripped of unnecessary scripts is typically 1.5–2.5 seconds on mobile.
Database maintenance and query optimisation
WordPress databases accumulate overhead. Post revisions, orphaned metadata, expired transients, and spam comments all add table size without adding value. On a site that has been running for several years, this overhead can add hundreds of milliseconds to query times.
WP-Optimize (free) handles routine cleanup: post revision limits, transient clearing, table optimisation. Run it monthly on a schedule.
The more significant problem is unindexed queries. When a plugin performs a database query on a column that has no index, MySQL performs a full table scan — reading every row to find the matches. On a small database this is negligible. On a WooCommerce store with 10,000 orders and 50,000 product meta rows, a single unindexed query can add 3–8 seconds to a page load.
Query Monitor shows you which queries are slow. If you see any query with a time above 100ms, investigate whether the column it queries has an index. Adding an index to a single column has resolved multi-second performance problems on more than one WooCommerce project I have worked on.
Is your WordPress site underperforming?
Use the intake form to describe your site. I will review it and tell you what I would look at first — no pitch, no commitment required.
Start the briefSources
- 1Core Web Vitals — web.dev (Google) — Official documentation on LCP, INP, and CLS thresholds and their impact on ranking.
- 2PageSpeed Insights — Google — Official tool for measuring Core Web Vitals and receiving field data from real Chrome users.
- 3Milliseconds Make Millions — Deloitte / Think with Google (2020) — 0.1s mobile load improvement = +8.4% conversions, +9.2% AOV across 40+ retail brands.
- 4WordPress Hosting Performance Benchmarks — Kinsta — Independent benchmarks of PHP execution, Redis object caching, and page generation times.
- 5WebP and AVIF support — Can I Use — Browser compatibility data confirming widespread WebP and AVIF support as of 2024.