WordPress speed optimisation
WordPress speed optimisation that starts by finding what is slow.
Most speed services install a caching plugin, run Lighthouse until the number goes green and send you the screenshot. That is not the work. The work is finding the one thing making your real visitors wait, on their phones, on their connection, and fixing that specific thing. Then proving it moved.
The short version
Fast and wrong is worse than slightly slower and correct.
A page served from cache in 80ms that shows last Tuesday's price is not a fast site. It is a broken one that happens to load quickly.
What most people optimise
- A lab score on the homepage, on desktop, with the cache warm
- Whatever the plugin's checklist happens to list
- Minification and concatenation, applied to everything, including the things that then break
- Deferring scripts until something important breaks, then undoing it
What moves the numbers
- Field data from real visitors, by template and device
- The largest element, and why it loads when it does
- Caching layers that agree and clear together
- Images generated once, not resized on every visit
Scope
What we look at to speed up WordPress.
Your site will not need all of it. Part of the job is telling you which parts to leave alone.
Multi layer caching
CDN edge cache at Cloudflare, OPcache for compiled PHP, Redis or Object Cache Pro for the object cache, and application level transients. Each layer helps. Each layer is also somewhere your content can get stuck.
Invalidation, properly
- Every layer holding a copy hears about each edit
- Includes deletions and pages that query content
- Get it wrong and a fast site serves stale pages
Image pipeline
AVIF and WebP with sensible fallbacks, real srcset and sizes so phones stop downloading desktop images, the right set of generated sizes, and bulk regeneration through WP-CLI so your existing library is fixed too, not just new uploads.
Render blocking and critical path
What has to be in the head, what can wait, and what should never have been loaded on that template at all. Fonts, third party tags and plugin assets enqueued site wide for one page that uses them.
FOUC and load flash guards
- Naive CSS deferral flashes unstyled content
- A lazy loaded hero leaves a blank box
- Both look broken and hurt the metric being fixed
Server and origin
Time to first byte on fully uncached requests, PHP version and workers, slow queries, Nginx and Apache config, and whether the origin is even involved in your problem. Often it is not.
The part nobody else builds
Four cache layers, and a cache that invalidates itself.
Turning caching on is easy. The hard part is a cache that clears itself correctly the second an editor changes anything, and that does not throw away the work it exists to protect while doing it. This is what runs on a high traffic directory site we own end to end.
The stack
Four layers, in request order
- CDN edge holds HTML for 24 hours via
s-maxage - OPcache keeps compiled PHP in memory
- Redis object cache holds results that would hit MySQL
- Transients cache the expensive parts of a template
The expensive mistake
Purge everything was cooling the image cache
- A full purge on every edit wiped the image cache
- Seven of eight sampled profile pages returned
MISS - Now a targeted purge of changed HTML only
- Images are never flushed any more
Triggers
Wired to every way state can change
- Post saves, status changes and comment events
- Meta added, updated and deleted, each hooked
- Location terms purged in both URL forms
- Landing pages that query content, enumerated separately
Restraint
Built so it cannot become the problem
- One purge per 60 seconds, 30 URLs per call
- Non-blocking, so publishing never waits on a CDN
- Image edits purge every size and the derived AVIF
- Six stale curated pages matched the origin at once
Image pipeline on the same site
Roughly 9,676 images rebuilt into a custom three size plus AVIF pipeline. Static assets serve with a one year max-age and return cache HIT. Profile images serve as AVIF with cf-cache-status: HIT, staying warm for around 19 hours and beyond, because nothing flushes them any more.
Evidence
One cache failure, four separate causes.
This is the job in miniature. Not a plugin setting, four unrelated faults that each broke the same thing.
Symptom
Six pages stale for a full day
- Edits took 14 to 24 hours to show live
- Fast, but serving people the wrong thing
- Origin requested with a cache buster was correct
- One test put the fault in the cache
Diagnosis
Four causes, not one
- URLs left off the purge list entirely
- No hook on meta deletion, so removals purged nothing
- Only one of two location term URLs cleared
- Curated pages beyond the reach of any term loop
How the diagnosis goes
Our first theory was wrong, and the data said so.
Card images flashed a placeholder while people scrolled. It looked exactly like a cold cache, so that is what we blamed first.
The theory we had to drop
It was not the cache
- Card images sampled at scroll depths 1 to 80
- Every one a cache
HIT, AVIF, 6 to 25 KB - Neither the bytes nor the delivery at fault
- Instinct would have wasted a day on a working cache
The real cause
Native lazy loading firing too late
- Images fetched only once nearly on screen
- IntersectionObserver promotes them about 1.5 screens ahead
- A
rootMarginof 1200px, AJAX images included - Distant images stay lazy, so bandwidth is saved
Core Web Vitals
Field data, not a screenshot.
Numbers from the same site, measured as field data in CrUX on throttled mobile. This is what the architecture above produces on a template with thousands of images behind it.
Gallery template
372ms
LCP. INP 51ms. The heaviest template on the site, and the fastest, because the images are pre-generated and the HTML is already at the edge.
Homepage
1032ms
LCP, roughly one second. INP 78ms. Slower than the gallery, and we know exactly why, which is why we measure per template, not per site.
Layout shift
0.00
CLS across the home, gallery and profile templates. Nothing moves under the visitor's thumb. Profile template lab LCP is 1528ms with CLS also at 0.00.
Lighthouse SEO on the same site scores 100 out of 100. We mention it last on purpose. It is the least interesting number here.
LCP
Usually the hero image or a heading held up by a font. The fix is rarely "compress the image", it is working out why the browser only discovered that resource halfway through the load.
CLS
Images without dimensions, banners injected above content, and web fonts swapping in at a different size. Cheap to fix and very visible to the person using your site.
INP
The one that replaced FID and the one that catches plugin heavy sites out. Long tasks on the main thread from tag managers, sliders and anything that binds to every element on the page.
Measured on your real templates before and after, per device. If a change did not move the field number, we will tell you that too.
Fit
Worth reading before you enquire.
Good fit if
- Failing Core Web Vitals despite the plugin settings
- Edits that appear hours later, or not at all
- A custom theme, WooCommerce or a lot of plugins
- Told to buy a bigger server and want that checked
Do not hire us if
- A specific Lighthouse number as the deliverable
- Cheap shared hosting you will not change
- Already under two seconds, only the lab score is low
- Swapping the theme for a page builder
How it runs
Measure, isolate, fix, measure again.
Baseline from real users
Field data by template and device, plus a trace of what your slowest real page is waiting on. Not one Lighthouse run on the homepage.
Free first lookIsolate the cause
Origin tested directly with a cache buster, layers checked one at a time. The point is to know which component is at fault before touching anything, so the fix is a decision, not a guess.
You approve the planImplement and verify
We write it, deploy it and check it live, including that content still updates when it should. Rollback path tested in advance on anything that touches caching.
Before and after, per templateCost
What it costs.
Performance work runs at £90 to £110 an hour. Where it is mixed with development it is billed at a £95 blended rate.
Diagnosis only
From £450
What is slow, why, and in what order to fix it, with the evidence. Around 4 to 6 hours. Hand it to any developer, including one of your own.
Fix the specific thing
Scoped
Caching rebuilt and invalidation made reliable, or the image pipeline sorted, or the critical path cleaned up. Fixed scope and cost agreed in writing first.
Ongoing
Monthly
For sites that keep changing, where a new plugin or a new template can undo the work. Field data watched, regressions caught before Search Console tells you.
Time is logged as it is spent and the ledger is open to you, including anything scrapped or reverted. Full breakdown on the rates page.
FAQ
Questions clients ask
Will you get me a 100 PageSpeed score?
Probably not, and we would not chase it. A 100 in Lighthouse is a lab result from a simulated phone on a simulated connection. Google ranks on field data, which is what real visitors on real devices experienced over the last 28 days.
We have seen sites score 98 in the lab and still fail Core Web Vitals in the field, usually because the lab run never loads the consent banner, the chat widget or the logged-in state. We optimise for the field numbers. The lab score usually improves anyway, it is just not the target.
Is a caching plugin enough?
Sometimes, and if that is your situation we will say so instead of selling you a project. A small brochure site on decent hosting with a page cache and sensible images is often fine.
Where it stops being enough is when you have a cart, a login, a search, personalised blocks or content that changes through the day. Then the interesting question is not what gets cached, it is what happens when it needs to stop being cached.
What is the most common thing you find?
Caching that works beautifully until something changes. Purge rules that cover the obvious URLs and miss the awkward ones. Nobody notices for months because the site is fast and looks correct, and the stale pages are the ones nobody on the team visits.
After that, it is images. Enormous originals scaled down in CSS, no AVIF, no proper srcset, and a hero image that is the largest element on the page loading last.
Do I need to move host?
Usually not, and we will tell you before you spend money on it. We once proved a site under a sustained attack was running at 7.5% CPU, which meant the bigger server the client was about to buy would have fixed nothing.
If your origin is the bottleneck, you will see it in the time to first byte on uncached requests and in the PHP worker queue, not in a Lighthouse screenshot. That is a measurable thing, so let us measure it before you migrate anything.
You keep writing optimisation with an s. Which is right?
Both. We are in the UK so we write optimisation, and plenty of people search for wordpress speed optimization service with a z. It is the same work either way, and Google has understood that for years.
Can you break my site doing this?
Speed work touches caching, asset loading and image handling, so yes, done carelessly it can break layout or serve people the wrong content. That is why nothing risky goes live without a tested rollback path, and why we check the result on your real pages instead of declaring victory from a score.
If the work involves a theme build, it runs through Git so any change can be reverted cleanly.
Keep reading
Related services
Book me
Tell us which page feels slow.
Send us a URL and what you are seeing. We will tell you what is holding it up, whether it is worth paying to fix, and whether you need us at all.