The SEO Case Study: Moving from 'Needs Improvement' to 'Good'
A real-world case study showing how one site improved Core Web Vitals from Poor to Good and the SEO traffic impact that followed.
A mid-size content publisher was losing organic traffic month over month. Their content was solid, backlinks were growing, but traffic kept declining. The culprit? Core Web Vitals.
This is the story of how they went from "Needs Improvement" to "Good" — and the traffic impact that followed.
The Starting Point
Performance Metrics (Before)
| Metric | Mobile Score | Status |
|---|---|---|
| LCP | 4.8s | ❌ Poor |
| CLS | 0.22 | ❌ Needs Improvement |
| INP | 380ms | ❌ Needs Improvement |
| Lighthouse | 34 | ❌ Poor |
SEO Metrics
- Organic traffic: declining 8% month-over-month
- Average position: dropping from 12 to 18
- Pages with "Good" CWV in Search Console: 12%
- Click-through rate: declining (lower positions = fewer clicks)
The Root Causes
- Unoptimized images — hero images were 2-4MB PNGs
- Ad scripts — 8 different ad network scripts loading synchronously
- No image dimensions — causing massive CLS from ads and images
- Heavy WordPress theme — 1.2MB of JavaScript, 400KB of CSS
- No CDN — serving from a single US origin server
- Render-blocking fonts — 6 font files loaded in the head
The Fix: A 6-Week Sprint
Week 1-2: Images
- Converted all images to WebP with AVIF fallback
- Implemented responsive images with
srcset - Added
widthandheightto every image - Set up lazy loading for below-fold images
- Result: LCP improved from 4.8s to 2.9s
Week 2-3: JavaScript
- Audited all third-party scripts
- Removed 3 unused ad networks and 2 abandoned analytics tools
- Deferred remaining ad scripts with lazy loading
- Replaced jQuery with vanilla JS for core functionality
- Result: TBT dropped from 1800ms to 400ms
Week 3-4: Layout Stability
- Added dimensions to all ad slots
- Implemented
font-display: optionalfor custom fonts - Reserved space for dynamic content (cookie banners, newsletter popups)
- Fixed a sidebar widget that shifted content on load
- Result: CLS improved from 0.22 to 0.04
Week 4-5: Infrastructure
- Added Cloudflare CDN (free tier)
- Enabled Brotli compression
- Implemented page-level caching (5-minute TTL)
- Upgraded to HTTP/2
- Result: TTFB dropped from 1.8s to 0.3s
Week 5-6: Fine-Tuning
- Inlined critical CSS
- Preloaded the LCP image on key pages
- Implemented service worker for repeat visitors
- Set up performance monitoring with alerts
- Result: Lighthouse mobile score reached 88
The Results
Performance Metrics (After)
| Metric | Before | After | Improvement |
|---|---|---|---|
| LCP | 4.8s | 1.6s | 67% faster |
| CLS | 0.22 | 0.04 | 82% better |
| INP | 380ms | 120ms | 68% faster |
| Lighthouse | 34 | 88 | +54 points |
| TTFB | 1.8s | 0.3s | 83% faster |
CrUX Update Timeline
- Week 1-2 after fixes: CrUX data beginning to improve
- Week 4: 50% of data reflects new performance
- Week 6: CrUX fully updated — all pages showing "Good"
- Week 8: Search Console CWV report shows 94% of pages "Good"
SEO Impact (Measured Over 3 Months)
| Metric | Before | After | Change |
|---|---|---|---|
| Organic sessions/month | 180,000 | 248,000 | +38% |
| Average position | 18 | 11 | +7 positions |
| Pages with Good CWV | 12% | 94% | +82 points |
| Organic CTR | 1.8% | 2.9% | +61% |
| Bounce rate | 62% | 41% | -34% |
| Pages/session | 1.4 | 2.1 | +50% |
Revenue Impact
- Ad revenue (more page views): +45%
- Affiliate revenue (lower bounce rate): +30%
- Newsletter signups (better engagement): +65%
- Total monthly revenue increase: +$28,000
What Made the Biggest Difference
In order of impact:
- Image optimization — the single biggest improvement to LCP
- CDN + caching — improved TTFB for all users globally
- Removing unused scripts — reduced TBT and improved INP
- Adding image dimensions — fixed CLS almost entirely
- Critical CSS — improved FCP and Speed Index
Key Takeaways
It's Not One Thing
There was no silver bullet. The improvement came from addressing all three Core Web Vitals systematically.
CrUX Data Updates Slowly
The hardest part was waiting 4-6 weeks for CrUX field data to reflect the changes. Stakeholders needed to understand this timeline.
SEO Impact Was Gradual
Rankings didn't jump overnight. The improvement rolled in over 2-3 months as Google processed the updated CWV signals.
Monitoring Prevented Regression
Two weeks after the project, a content editor uploaded a 4MB image that tanked LCP on the homepage. The performance alert caught it within hours.
Don't Wait for Traffic Loss
This site waited until traffic was declining to address performance. Don't make the same mistake — monitor proactively.
Ready to stop wasting ad spend?
Track your landing page performance, monitor Core Web Vitals, and calculate exactly how much slow pages cost you.
Start Free — No Credit Card