How to Actually Speed Up a Slow WordPress Site

A client once messaged me at 11pm: “Our site feels slow.” No numbers, no page, just a feeling. That vague complaint turned into a three-day audit which ended with the real culprit being a single slider plugin loading 1.8MB of JavaScript on every page, including the contact form. Fixing it took twenty minutes. Finding it took three days.

That is usually how WordPress performance work goes. The fix is cheap; the diagnosis is where the time goes. So here is the order I actually work in, after years of doing this on client sites and on my own.

Measure first, and measure the right page

Most people test their homepage, see a decent score, and assume the site is fine. But the homepage is often the most optimised page on a WordPress install, because it is the one everyone looks at. Your slow pages are usually the archive listing, a product category with 40 items, or a page built by a page builder with six nested rows.

Test at least four URLs before you touch anything:

  • Homepage
  • A single post or single product page
  • An archive or category listing page
  • Whatever page your analytics says gets the most traffic

Use PageSpeed Insights for the Core Web Vitals numbers and field data, and WebPageTest or GTmetrix for the waterfall. The waterfall is the part that matters. A score of 62 tells you nothing actionable; a waterfall that shows a 2.4 second gap before the first byte tells you the problem is server-side, not front-end. Write down TTFB, Largest Contentful Paint, and total page weight for each URL. Without those four numbers you cannot tell whether your later changes helped or just felt like they did.

Fix TTFB before you compress a single image

If Time To First Byte is above roughly 600ms, front-end optimisation is mostly wasted effort. You are shaving 200ms off a page that spends two seconds waiting on PHP.

The usual causes, in the order I find them:

  • Shared hosting that is genuinely oversubscribed. No amount of caching fixes a host that gives you a fraction of a CPU core. If TTFB is inconsistent, sometimes 400ms and sometimes 3 seconds, on identical requests, that is a hosting problem.
  • An old PHP version. Sites still running PHP 7.4 in 2026 exist in surprising numbers. Moving to PHP 8.2 or 8.3 typically cuts execution time by 20 to 30 percent for free.
  • A bloated wp_options table. Run a query for autoloaded options: SELECT SUM(LENGTH(option_value)) FROM wp_options WHERE autoload = 'yes'; If that number is over about 1MB, every single request is loading it. I have seen 14MB on a site where an abandoned plugin was writing transients that never expired.
  • No object cache. On any site with more than a few hundred posts, Redis or Memcached for the object cache is one of the highest-leverage changes available.

Install Query Monitor and look at the query count and the slowest queries on your worst page. A well-behaved WordPress page does 30 to 80 queries. If you see 400, one of your plugins is running a query inside a loop, and that is your target.

Audit plugins by what they load, not by how many there are

“Deactivate plugins to speed up your site” is advice that gets repeated without nuance. Thirty lightweight plugins can be faster than five heavy ones. What matters is what each one puts on the page.

The practical method: open the Network tab on your slowest page, sort assets by size, and trace each large CSS or JS file back to its plugin folder in the URL path. This takes fifteen minutes and it is far more useful than guessing.

What I look for specifically:

  • Plugins loading assets site-wide when they are needed on one page. Contact forms, sliders, table plugins and social share widgets are the repeat offenders. Either use a plugin like Asset CleanUp / Perfmatters to dequeue them conditionally, or write the conditional dequeue yourself in a small mu-plugin.
  • Multiple plugins solving the same problem. Two caching plugins, or an SEO plugin plus a separate schema plugin, usually means duplicated work and occasionally conflicting output.
  • Anything phoning home on page load. A licence check or external API call in a front-end hook will add whatever the remote server’s latency is to your TTFB. Query Monitor’s HTTP API panel exposes these.

Also worth checking: how many admin-ajax or REST requests fire on a normal page view. Heartbeat and over-eager plugins can add several requests per minute per visitor, which does nothing for the visitor and plenty to your server load.

Images, fonts and the LCP element

Once the server side is honest, front-end work actually pays off. Page weight on most WordPress sites is 60 to 80 percent images, so this is where the easy wins live.

Convert to WebP or AVIF. On a portfolio site I rebuilt last year, converting 240 JPEGs to WebP took total page weight from 4.1MB to 1.3MB with no visible quality difference. Then check that your theme is actually serving responsive sizes: view source and confirm your <img> tags have a real srcset. Page builders sometimes output a hardcoded full-size image, which means a phone downloads a 2400px file to display it at 380px.

Two specifics that move LCP more than anything else:

  • Never lazy-load the hero image. Lazy loading your LCP element delays it by design. Exclude above-the-fold images from lazy loading and add fetchpriority="high" to the hero.
  • Self-host fonts and preload them. Google Fonts loaded from a remote domain costs a DNS lookup plus a connection before any text renders. Self-host the two weights you actually use, use font-display: swap, and drop the rest. Most sites load six weights and use two.

Cache last, and verify it is working

Caching is the step everyone starts with and it should be the step you finish with, because a cache layered over a slow site just hides the problem until a logged-in user or an uncached URL exposes it again.

Set up page caching, browser caching headers, and a CDN in front. Then verify: request a page twice with curl -I and look for the cache header your plugin sets. Check the pages that must not be cached, cart, checkout, account, are actually excluded. And test as a logged-out visitor in a private window, because as an admin you are usually bypassing the cache entirely and seeing the slow path.

Re-run your four test URLs and compare against the numbers you wrote down at the start. If TTFB, LCP and page weight have not all moved, something you changed did not do what you thought it did.

The takeaway

The order matters more than the tools. Measure real pages, fix the server before the front-end, audit plugins by their payload rather than their count, deal with images and fonts, and cache at the end. Most sites I look at do not need a new theme or a migration; they need one plugin dequeued from 40 pages where it was never used.

And keep the before-and-after numbers. “Feels faster” is not a result you can defend to a client, and it is not a result you can trust yourself.

Faizan Khan
Faizan Khan

Technical PM & PHP developer — the manager who still ships code. 13 years turning “can we build this?” into “it’s live”.

Work with me →

Enough talk. Let’s launch.

One call. An honest scope, a real timeline, and weekly updates until it ships.