Why does a WordPress performance audit have to come before any optimisation work?

43.0% / 60.2%
WordPress share of all websites and of the CMS market, per W3Techs December 2025. The largest CMS surface area = the largest optimisation surface.
~43.4%
share of WordPress sites that pass all three Core Web Vitals on mobile (mid-2025), versus ~65% for Shopify and ~60% for Wix, per Search Engine Journal / HTTP Archive CrUX 2025.
96% / +34% YoY
share of 2024 WordPress vulnerabilities that originated in plugins (4% themes, <0.1% core); 7,966 new disclosures, a 34% year-over-year jump, per Patchstack State of WordPress Security 2025.

Most modernisation work I have walked into starts the same way. The team is already mid-fix. They added object cache. They moved to a faster host. They installed two image plugins and a third one to manage the first two. The site is still slow, and now nobody can describe what changed last.

The hardest part of WordPress performance work is restraint. Before any change, run an audit and write the numbers down. Without telemetry, every fix is a guess and every guess is expensive.

The audit has four cheap inputs. Pull a real waterfall from PageSpeed Insights against three different page types: the homepage, a long article, and a typical category archive. Then run Query Monitor on a logged-in admin session and capture the slow queries on each of those page types. Pull a plugin map: every active plugin, its update cadence, and the date it was last touched by anyone. Finally, ask the host for the actual PHP version, OPcache settings, and whether object cache is on.

That single hour of measurement is the most valuable hour of the project. It also tells you which fixes will not move the dial. The team that “added object cache and saw no change” did not have a CPU problem; they had a render-blocking JS problem. The audit makes that visible before anyone touches code.

If you are running this on someone else’s site or do not have host-level access, our platform modernisation work always starts with the same list, in the same order. Skip a step and the rest of the project drifts.

~58%
share of mobile WordPress sites that fail Core Web Vitals on first measurement, per HTTP Archive’s 2025 Web Almanac.
3 of 5
slow page-loads on a typical SMB WP site come from one or two plugins, not the host or the theme.
12 weeks
a complete modernisation engagement on a 50k-page WP site, including SEO parity testing.

Before we wrote our internal audit checklist, we used to skip telemetry on small sites because “it would only take an hour to fix”. Almost every time, that hour grew into three days because the change was made in the wrong layer. The discipline came from getting burned. Now nobody on our team starts with a code change. The same shape applies if you read our note on how modern product teams structure delivery: measurement before mutation, every time.

How does plugin bloat silently slow WordPress in 2026?

The fastest WordPress sites I have worked on do not run more plugins better. They run fewer plugins, period. There is no clever way to host eighty plugins. Every active plugin contributes some combination of: extra hooks on every request, blocking JS in the head, an admin-side cron job, a database table that nobody reads, and a maintenance burden somebody owns even if they did not realise.

The plugin map from the audit is where you start. Sort by “what does this do for the user”. On a real client site, we counted thirty-two active plugins; six provided user-facing features, four provided admin-side features the team actually used, and the rest were either redundant (three SEO plugins layered on top of each other) or ghosts left behind by previous staff.

The harder cut is not “what looks redundant” but “what fights itself”. Two caching plugins are worse than one. A page-builder plus a separate accordion plugin loads two competing JS frameworks. An image plugin that resizes on upload plus a CDN that resizes on the fly will compete and produce broken responsive sets. Identify the conflicts and pick a side.

Replace, do not stack. If the goal is image optimisation, choose the modern path: native WordPress image sizes plus a host-level or CDN-level format converter, configured once. Drop the plugin layer entirely. The same logic applies for caching, security, and analytics. Layered solutions look safe; they make every page slower for the rest of the site’s life.

Common mistake

Disabling a plugin does not always remove it. Some plugins write CSS or JS into the page from the database even when deactivated, and many leave their custom tables behind. After a plugin removal, run a real migration: delete the plugin’s options, drop its tables, and confirm the front-end no longer enqueues its assets. Otherwise the deactivated plugin will keep costing you on every request.

If your team cannot list every plugin and what it does without checking, you do not have a plugin policy. You have a plugin graveyard.

Vadim Leviev · Levievs

Database queries are the slowest tier

For sites past a few hundred posts, the database is usually the slowest tier and the one most teams ignore. Caching disguises the problem. Once cache misses or warm-up periods hit, the queries that were always slow become user-visible.

The Query Monitor output from the audit gives you the data. Look for three patterns. First, queries on autoload options: WP loads wp_options on every request, and a single bloated row (a 10MB transient that never expired, for example) drags every page. 10up’s engineering guide has the cleanup pattern documented; the short version is, never store anything bigger than a few KB with autoload=true.

Second, slow main-loop queries on archive pages. WP_Query with a meta_query on an unindexed meta key on a 100k-post site will scan millions of rows. The fix is rarely “cache the page”; the fix is to index the meta key, or restructure the data so the query is on a real column. Cache layered on top of an O(N) query is still going to fail under traffic.

Third, plugin-driven cron queries that run at midnight on a single-server install and then bring the site down for two minutes. Move WP-Cron to a real system cron, audit which plugins use cron, and either rate-limit them or replace them. The default WP-Cron model assumes traffic; on a quiet site, jobs queue up and then run all at once when somebody finally visits.

Object cache, when present, hides almost all of this. Without object cache, expect each of these patterns to add 100 to 500 milliseconds per page load, and that is on a fast host. Our development team treats query review as a code-review check; once the budget exists, regressions are caught at PR time instead of at user-incident time.

In what order should caching be applied to a WordPress stack?

The single most consistent mistake we see is teams installing a CDN before any other caching layer. Caching has an order, and reversing it makes the problem worse, not better.

  1. Object cache (Redis or Memcached)

    This is the foundation. Object cache stores the result of every database query, autoloaded option, and computed piece of state. Without it, page-cache hit-rate decides everything; with it, even a cache miss is fast. If you do nothing else, install Redis on the host and connect it via a maintained drop-in.

  2. Page cache (server-level, not plugin)

    Run page caching at the web-server tier (NGINX FastCGI cache, or a maintained host’s built-in equivalent). Plugin-based page caches add PHP overhead before they cache; server-level caches skip PHP entirely on a hit. The difference is significant: server-level page cache can serve in 5 to 20 milliseconds. Plugin-cache rarely beats 80.

  3. CDN cache (last, not first)

    A CDN is for static assets and edge replication of full-page HTML where the user is far from your origin. It is not a fix for a slow origin. If your origin is slow, the CDN serves the slow page faster the first time and just as slow on every cache miss. Get the origin under 200ms first.

  4. Browser cache and asset hygiene

    Set explicit cache headers on every static asset, fingerprint URLs (theme, plugin, image), and audit your CSS and JS for genuinely needed bytes. Google’s LCP guidance covers the asset-side fixes that move the most for the least work.

  5. Avoid cache stacking

    Pick one page-cache layer and one CDN. Two page caches will fight each other on purge events and produce stale content for users while looking fresh in the dashboard. The rule we use: every cache layer must have one owner, one purge mechanism, and one log to read.

Teams using AI-assisted tooling to refactor legacy code can compress part of this work, especially the plugin replacement phase. We wrote a longer note on where AI web-development tools actually help and where they do not.

Slow WordPress?

Get a one-week audit, the same we run before any modernisation.

You will get the audit report, a prioritised punch list of fixes, and a fixed-price quote for the work, ordered by impact-to-effort.

See modernisation work →

Images and assets without breaking SEO

Images are still the biggest payload on most pages, and the modernisation step that moves Core Web Vitals the fastest. The mistake is to fix it through a plugin and skip the asset pipeline. The right shape: WordPress generates a small set of explicit sizes on upload, the CDN converts those sizes to WebP or AVIF on the fly, and the front-end uses native srcset so browsers pick the right one.

Lazy-loading is on by default in WP 5.5 and later, but only for img elements that have width and height attributes. Page-builder content often strips those attributes, defeating native lazy-load. Audit your content templates and put dimensions back. The cost is zero, the gain on long pages is real.

The SEO trap is in URL changes. If you migrate image storage from the WP uploads directory to a CDN with a different URL pattern, you need to either keep the old URLs valid as redirects or update every backlink and feed reference to the new path. Search engines do not rebuild image indexes quickly, and broken image references tank social previews silently for months.

Asset pipeline that does not break

Five rules we apply on every modernisation

  • Generate fewer image sizes, but the right ones (mobile, tablet, desktop, retina-desktop).
  • Convert to WebP or AVIF at the CDN, not in WordPress, so the original stays as a clean source.
  • Always set explicit width and height on every img, even after a page-builder runs.
  • Defer everything that is not above-the-fold; eager-load only the LCP image.
  • Keep old image URLs valid through 301 redirects for at least six months after any migration.

When the strangler glass breaks

Modernisation is not migration. We migrate as a last resort, after we have run the audit and decided that the platform itself is the constraint. That conclusion is rarer than vendor decks suggest. Most WordPress sites can be modernised in place and triple their speed without changing CMS.

The signals that say “migrate” are concrete. The current host cannot give you Redis, OPcache, or PHP 8.x and there is no path to switch host without losing data integrity. Your traffic regularly exceeds what the architecture can serve, even with full caching. The number of paid plugins required to keep the site stable is now larger than the number of features your team actually maintains. Or the editorial workflow has outgrown the WP admin and is now blocking the team monthly.

When migration is the answer, run it incrementally. The strangler pattern works for content sites: stand up the new platform, route specific URL patterns to it through your CDN or load balancer, migrate one section at a time with parity testing, and only retire the legacy when every URL is served by the new system. We covered the organisational side of this in our note on continuous transformation; the engineering side is the same shape, just smaller windows.

If you do go for a migration, the parity test is the unglamorous heart of it. Crawl your live site, capture the rendered HTML for every URL, then run the same crawl against the new platform and diff. Differences are not bugs; differences are decisions you forgot to make. The diff is also where the SEO regressions are caught before they ship.

TL;DR

Modernise WordPress in this order: measure first, cut plugins, fix queries, layer cache from object to CDN, fix images, then migrate only if the platform itself is the constraint. Most sites do not need migration; they need a one-week audit and someone willing to disagree with the obvious-sounding fix.

When the audit points to a custom plugin (and sometimes it should), the next decision is the build-versus-buy framing. We covered the five-signal version in our piece on custom WordPress plugin development.

Frequently asked questions

How long does a WordPress modernisation take?

Six to twelve weeks for a 50k-page site, including parity testing. The audit is week one. The plugin and query work is weeks two through four. Caching, asset pipeline, and migration parity run in parallel from week three. The final two weeks are SEO regression checks and a clean handover.

Will we lose SEO during modernisation?

Not if you keep URLs and structured data unchanged, redirect any URL pattern that does change, and run a crawl-diff before and after each major step. Most regressions happen because someone changed image paths, removed a category, or shipped a redesign that altered h1 structure without telling SEO.

Do we need to switch off WordPress entirely?

Almost never for content sites. WordPress on a modern host with object cache, server-level page cache, and a tight plugin set is faster than most headless setups people think they need. We migrate when the editorial workflow has truly outgrown WP, not because the CMS itself is slow.

What is the rollback plan if a migration goes wrong?

Route-level rollback at the CDN. Every section of the new platform is enabled or disabled by a routing rule; if a regression appears, flip the rule and the legacy serves that section while the bug is fixed. We never run a hard cut-over without a tested route-level fallback.

How do we keep performance after modernisation?

Three habits. Quarterly plugin review, automated weekly Lighthouse CI on the top thirty pages, and a query budget that is treated as a code-review check. Performance regressions creep in through plugin updates and editorial changes; if nobody is watching, you are back at the audit baseline within a year.