PageSpeed scores are one of those things that feel abstract — until a client tells you their bounce rate is 74% and they're losing customers to a competitor whose site loads in under two seconds.
This is the full breakdown of a real project: Snowden Electrical, an Auckland-based electrical contractor. Their site was scoring 54 on Google PageSpeed (mobile) when they came to me. It left on 94. Here's exactly what I found, what I changed, and what happened to the business as a result.
The Brief
James Snowden had a WordPress site built 18 months earlier by a local agency. It looked fine — professional header, services listed, contact form. But it was slow. Visitors were landing on it from Google Ads and leaving before the page finished loading. The conversion rate on paid traffic was under 1%.
His brief was simple: “Fix the speed. I don't care what it takes.”
Before & After — The Numbers
| Metric | Before | After |
|---|---|---|
| PageSpeed Mobile | 54 | 94 |
| PageSpeed Desktop | 68 | 97 |
| LCP | 6.2 s | 1.4 s |
| CLS | 0.18 | 0.02 |
| INP | 340 ms | 68 ms |
| Page Size | 4.8 MB | 890 KB |
| HTTP Requests | 72 | 18 |
Tested with Google PageSpeed Insights on mobile (Moto G Power, fast 4G). Scores captured before and 48 hours after deployment.
The Audit — What I Found
Before touching a single file, I ran the site through Google PageSpeed Insights, GTmetrix, and Chrome DevTools Performance panel. The problems weren't hidden — they were stacked one on top of the other.
Hero image — 1.8 MB uncompressed PNG
Caused LCP to spike to 6.2 s on mobile
Elementor page builder
Loaded 14 separate JS files on every page — including pages that used zero Elementor blocks
11 active plugins, 4 doing the same job
Conflicting SEO plugins, duplicate caching attempts, multiple form handlers
Google Fonts loading from google.com
Two separate render-blocking stylesheet requests before any text painted
No caching at all
Every request hit PHP + MySQL from scratch
Images served at full upload size
A 150 × 150 px thumbnail was loading a 1,400 × 1,400 px file
No CDN
All assets served from a shared hosting server in the US
The core problem: The site was built with Elementor — a page builder that solves a design problem by creating a performance problem. Pages that took 45 minutes to design took 6 seconds to load. That trade-off is unacceptable when you're running paid traffic to the site.
The Fixes — Step by Step
I didn't start by installing a speed plugin and calling it done. I worked through the root causes in order of impact — biggest wins first.
Rebuilt the Theme — No Page Builder
The entire site ran on Elementor. Every page loaded Elementor's core JS bundle (189 KB minified) even on static content pages. I rebuilt the theme from scratch in PHP — custom templates for each page type, no builder dependency. This alone dropped HTTP requests from 72 to 31.
Converted All Images to WebP and Added Lazy Loading
The hero image was a 1,800 × 900 PNG at 1.8 MB. I converted it to WebP (dropped to 180 KB), added explicit width/height attributes to eliminate layout shift, and set loading='lazy' on every below-fold image. The hero also got a preload hint so browsers fetch it in parallel with CSS.
Hosted Google Fonts Locally
Two Google Fonts were loading from fonts.googleapis.com — a separate DNS lookup, TLS handshake, and render-blocking stylesheet request before any text could paint. I downloaded the font files, hosted them on the same server, and inlined the @font-face declarations in the main stylesheet. Text-render time dropped by ~400 ms.
Plugin Audit — From 11 to 5
11 active plugins including two SEO plugins (Yoast + Rank Math — they conflict), a social sharing plugin loading JS on every page for 3 tiny icons (replaced with inline SVG), a contact form builder used on one page, and a legacy slider plugin not used anywhere but still enqueueing scripts. Kept 5 essential plugins. Removed the rest.
Implemented Caching with WP Rocket
The site had no caching — every page load was a fresh PHP execution + 4–6 database queries. WP Rocket added full-page caching (cache lifetime: 10 hours), combined and minified CSS/JS, and enabled browser caching headers. Repeat visitors now get static HTML files served in under 60 ms.
Added Cloudflare CDN
Static assets (CSS, JS, images, fonts) were being served from a shared US server — adding ~180 ms of latency for NZ visitors. Cloudflare's free tier put those assets on an edge node in Auckland. Time to first byte for NZ visitors dropped from 480 ms to under 100 ms.
Fixed Layout Shift (CLS 0.18 → 0.02)
CLS of 0.18 was caused by three things: images without dimensions (browser didn't know how much space to reserve), web fonts loading late and causing text reflow, and a cookie banner appearing 1.5 seconds after load and pushing content down. Fixed by: adding explicit width/height to all images, using font-display: swap with preloaded fonts, and moving the cookie banner to a fixed overlay that doesn't affect layout.
What Each Fix Actually Contributed
Not all optimisations are equal. Here's an honest breakdown of where the score improvement actually came from:
Approximate contributions measured at each stage of deployment. Individual gains may overlap.
The Business Result
James sent a message 30 days after launch. I'll quote him directly:
“The site loads immediately now. We're getting double the enquiries from the same Google Ads spend. Our enquiry rate went from about 1.2% to just over 3%. That's paying for this project every month.”
The same ad budget that previously converted at 1.2% was now converting at 3.1%. For a business spending NZD $800/month on Google Ads, that's not a marginal improvement — it's the difference between ads that cost money and ads that make money.
Google also rewarded the faster load times in organic search. The site moved from page 3 to page 1 for “electrician Auckland” within 6 weeks of the relaunch — a combination of Core Web Vitals improvement and the schema markup added during the rebuild.
Tools I Used on This Project
Google PageSpeed Insights
Primary scoring tool — measures real-world CWV data
GTmetrix
Waterfall chart to identify exactly which resources caused delays
Chrome DevTools
Performance panel for LCP/CLS frame analysis
Squoosh
Image compression and WebP conversion
WP Rocket
Caching, minification, and lazy loading
Cloudflare
Free CDN — edge nodes in Auckland for NZ visitors
Key Takeaways
Page builders are the biggest single cause of slow WordPress sites
Not always, and not without workarounds — but a hand-coded theme starts at 18 HTTP requests. An Elementor site starts at 55+. That gap is almost impossible to close after the fact.
Your LCP element determines your score more than anything else
On most business sites, LCP is the hero image. If that image is a 1.8 MB PNG, nothing else you do will move the needle. Start there.
Google Fonts is a surprisingly expensive request
Most developers don't think twice about adding Google Fonts. It's a DNS lookup, a TLS handshake, and a render-blocking stylesheet — adding 300–500 ms to first contentful paint. Host fonts locally.
A PageSpeed score is a business problem, not a technical one
A site scoring 54 isn't just failing a benchmark. It's converting at 1.2% instead of 3%+. Every month the slow site runs, it's costing more than the fix would have.
Is Your WordPress Site Slow?
Run your site through PageSpeed Insights and check your mobile score. Under 70 is worth fixing. Under 50 is costing you conversions right now.
- →Score under 70 — your LCP, image sizes, or render-blocking resources are the likely culprit
- →CLS above 0.1 — images without dimensions or late-loading fonts are causing content to jump
- →INP above 200 ms — too much JavaScript executing on the main thread, usually a page builder