The short version
If your WordPress site is slow, the cause is almost certainly one of three things, in this order:
- Too much stuff loading before the page can show up. Stylesheets, fonts, and scripts that block the browser from painting anything for the first second or two.
- Plugins doing too much. Most WordPress sites accumulate plugins, and most plugins quietly load their code on every page whether or not their feature is being used there.
- Images that are far bigger than they need to be. A 2.4MB hero image where 240KB would do.
That's most of it.
There are fancier diagnoses (server tuning, database indexes, DNS prefetch hints) and they sometimes matter, but they almost never matter first. Working on the fancy stuff before fixing the three above is like sweeping the floor of a leaking boat.
The rest of this post is about why those three matter, how to tell whether they're the actual problem on your site, and what an honest fix looks like.
How a browser actually loads a WordPress page
Before the diagnoses, a quick walkthrough of what happens when someone clicks a link to your site. This matters because most of the wrong diagnoses skip this step.
In plain terms:
- The HTML doesn't arrive instantly. WordPress runs, asks the database for content, and assembles the response. This takes anywhere from 100 milliseconds (good) to several seconds (bad, and a separate problem).
- Once the HTML arrives, the browser then has to fetch a load of other things (stylesheets, scripts, fonts, images) before it can finish drawing the page.
- Render-blocking resources are the files in that "other things" list that the browser has to wait for before it can show anything. Too many of those, or files that are too big, and your visitor stares at a white screen.
- Largest Contentful Paint (LCP) is the metric Google cares about most. It measures how long until the biggest visible element on the page (usually a hero image or large heading) actually appears.
Once you understand that flow, you can spot a wrong diagnosis at a glance. "My server response is fast but my LCP is four seconds" tells you the server's fine and the browser is starving for resources further down the chain. Different problem, different fix.
Problem 1: too much stuff loading before the page shows up
The most common pattern I see on slow WordPress sites: a 2026-vintage page loading like a 2012-vintage page because it's blocked behind hundreds of kilobytes of CSS and a couple of megabytes of JavaScript before the browser is allowed to paint a single pixel.
Here's what that looks like in a Lighthouse report:
[!] Eliminate render-blocking resources — Est. savings: 1,640 ms
/wp-content/themes/example/style.css (220 KB)
/wp-content/plugins/example/css/main.css (84 KB)
/wp-content/plugins/another/js/widget.js (640 KB)
/wp-content/plugins/yet-another/js/lib.js (210 KB)Four files, more than a megabyte total, and the browser has to wait for all of them before showing your visitor anything. That's roughly 1.6 seconds of staring at a blank screen. On a phone with a patchy connection, longer.
The good news: this is fixable, often dramatically, often without changing anything visible about the site. The fixes:
- Inline the most important CSS for the part of the page visitors see first. Defer the rest until later.
- Defer or load JavaScript asynchronously so it doesn't block the browser during the initial render.
- Remove plugins that ship code to every page even when their feature isn't being used. A booking plugin loading its calendar widget on your About page is a real example I've seen many times.
- Self-host fonts rather than calling Google Fonts mid-render.
A good caching plugin (I usually reach for WP Rocket or LiteSpeed Cache) handles the first two with a couple of toggles. The third needs a developer's eye. The fourth is a five-minute job that almost no one does.
Problem 2: plugins doing too much
A WordPress site with 47 active plugins isn't necessarily slow, but it's almost always slower than it needs to be. The reason isn't the plugin count itself; it's that most plugins load their code everywhere on the site, regardless of whether the visitor is on a page where that plugin's feature is being used.
The questions worth asking when auditing a plugin list:
- Is the plugin still being used? Sites accumulate. A plugin installed two years ago for a one-off campaign is still running. Deactivate anything dormant.
- Is the plugin loading code on pages where it doesn't need to? A booking plugin should load its widget on the booking page, not on every page. Most plugins do the lazy thing and load themselves everywhere; tools like Asset CleanUp or Perfmatters let you scope them down.
- Could the plugin be replaced with something lighter? A 600KB modal popup plugin can usually be replaced with thirty lines of code that nobody has to maintain.
Auditing a plugin list takes longer than the rest of the work combined, because it's thinking time, not configuration time. It's also where the biggest improvements usually come from. A site where I've removed twelve plugins, scoped down five more, and replaced two with lighter alternatives is almost always meaningfully faster than the same site with caching tweaks alone.
Problem 3: oversized images
The third most common diagnosis. Easier to fix than the first two, often skipped because it's unglamorous.
The patterns I see again and again:
- A hero image that's 2.4MB instead of 240KB
- Product images served at 4096 pixels wide on a 600-pixel-wide product card
- PNGs used for photographs (a JPEG or WebP would be 80% smaller, identical to the eye)
- Lazy loading either turned off entirely, or applied to images visible above the fold (which slows the page rather than speeding it up)
- No modern image formats. AVIF and WebP combined cover roughly 96% of browsers in 2026, but plenty of sites still serve only JPEGs.
The fix isn't dramatic. Pick a tool (ShortPixel, Imagify, Smush, EWWW), let it convert and resize the existing media library, and configure WordPress to generate appropriately-sized versions of new uploads automatically.
For larger media libraries this is hours of compute time but very little human work. Worth doing.
// In wp-config.php, ensure WordPress is generating responsive images
// at sensible sizes:
add_filter('big_image_size_threshold', function() {
return 2048; // resize uploads larger than 2048px on the long edge
});What people think is wrong (but usually isn't)
A list of misdiagnoses I hear regularly:
- "It's because we have too many plugins." As above, the count isn't the problem. A site with sixty well-behaved plugins can outperform a site with eight badly-behaved ones.
- "WordPress is just slow." WordPress itself is fast. The default install on a decent host returns its first byte in under 200 milliseconds. If your site's response time is 1.5 seconds, the cause is somewhere else.
- "It's the host." Sometimes. But usually the host is fine and the site is asking the host to do too much work on each request. Move from a slow host to a fast one and you'll see a 200-millisecond improvement; fix the things in this post and you'll see a two-second improvement.
- "My server needs more RAM or CPU." Almost never. The diagnostic for "needs a bigger server" is concurrent traffic during a busy period, not an inherently slow site at quiet hours.
If you've been told one of the above and your site is slow at low traffic, get a second opinion. These are the diagnoses that get sold to clients because they sound like real engineering, but they don't fix the actual problem.
What an audit report should tell you
If you've paid for a performance audit (or you're about to), here's what a useful one looks like:
- A clear baseline. Real numbers from real tools, captured in one place, that you can compare against later.
- A diagnosis you can read. Not just "your LCP is 4.2 seconds" but "your LCP is 4.2 seconds because of these three specific things."
- A prioritised list of fixes. Not everything is worth fixing. The audit should tell you what's worth doing first, what's worth doing eventually, and what's not worth doing at all.
- What's outside the developer's control. Some performance problems are hosting decisions. Some are design decisions. Some are content decisions. A good audit calls those out separately so you can make the right call.
If the audit you've received is a Lighthouse screenshot with a list of plugins to install, it's not really an audit. It's a sales pitch with technical decoration.
What an honest performance engagement looks like
When I take on a performance audit, the rough shape is:
- Measure the starting point. Lighthouse, PageSpeed Insights, GTmetrix, and WebPageTest, with the field data from real visitors where available. Capture the numbers so we have a baseline.
- Diagnose what's actually slow. Render-blocking, plugin behaviour, image sizing, server response. Often a specific combination, not a single villain.
- Prioritise by impact. A five-minute fix that saves 800 milliseconds is worth more than a four-hour fix that saves 200.
- Implement. Caching configuration, plugin audit, image work, the unsexy detail work.
- Measure again. Same tools, same conditions, side by side.
- Write up what changed. A summary you can read, a summary your developer (current or future) can act on.
The thing I won't do is tell you up front that you'll see a specific percentage gain. The honest answer depends entirely on the starting point, and I'd rather measure than guess. Most engagements produce significant improvements; I'm not putting a number on that until I've looked under the hood.
If your site is slow and you'd like a diagnosis, get in touch. If it's slow and you already have a maintenance arrangement with someone, the same applies. Performance work is usually a single engagement rather than an ongoing one, and second opinions are part of how this industry stays honest.
For ongoing care once a site's running well, the maintenance service covers it.
Further reading
- web.dev: Largest Contentful Paint — the canonical reference on the metric Google cares about most
- Chrome Lighthouse documentation — useful for understanding why Lighthouse flags what it flags
- Cloudflare APO — automatic page optimisation; not always the right answer but worth knowing exists
- WP Rocket — the caching plugin I most often reach for
- The full list of performance tools I work with lives on the Tools page