Performance work has a reputation for being endless. Teams install a caching plugin, see a small improvement, install another, and six months later the site is slower than when they started. The fix is not more plugins; it is sequencing. You find the single biggest cause of each failing metric, fix it, measure, and only then move to the next.
viraaprofessional.com is a B2B professional services site we run SEO for. It is built on WordPress and, like many business sites that grow quickly, it had accumulated plugins, scripts and large images without anyone checking the cost. This Core Web Vitals case study documents how we took it from failing to passing using RankStreet's audit as the diagnostic and Google PageSpeed Insights as the verifier.
Why a Core Web Vitals case study matters for SEO in 2026
Core Web Vitals are Google's three user-experience metrics: Largest Contentful Paint (LCP) for loading, Interaction to Next Paint (INP) for responsiveness, and Cumulative Layout Shift (CLS) for visual stability. Google's documented "good" thresholds are LCP at or below 2.5 seconds, INP at or below 200 milliseconds and CLS at or below 0.1, assessed at the 75th percentile of page loads.
Google has been clear that page experience is one signal among many, and that great content on a slow page can still outrank thin content on a fast one. So why invest? Three reasons:
- Tie-breaking. In competitive B2B niches, many pages are similarly relevant. Experience signals help decide between near-equals.
- Visitors. A slow, jumpy page loses people before they read a word, regardless of how it ranks.
- Machines. AI crawlers and agents that fetch pages on a user's behalf operate under time budgets. A page that takes six seconds to render its main content is a worse candidate for retrieval than one that renders in two. We frame that as a reasonable expectation for 2027 rather than a documented ranking rule, but it is another reason not to treat speed as optional.
The starting point
The baseline from PageSpeed Insights, which RankStreet surfaces inside its performance section, looked like this:
| Metric | Mobile | Desktop | Good threshold |
|---|---|---|---|
| LCP | 6.2s | 3.9s | ≤ 2.5s |
| INP | 418ms | 232ms | ≤ 200ms |
| CLS | 0.28 | 0.19 | ≤ 0.10 |
| PSI performance score | 32 | 58 | 90+ |
Failing on every metric, on both devices. The overall RankStreet audit score was 43/100. Before touching anything, we wrote down a hypothesis for each metric based on what the audit flagged:
- LCP: oversized hero and above-the-fold images, plus slow server response.
- CLS: images without dimension attributes, and late-loading fonts.
- INP: third-party scripts and unused plugin JavaScript hogging the main thread.
Writing hypotheses down sounds pedantic. It stops teams changing ten things at once and then not knowing which one worked.
Week 1: image discipline (the biggest single win)
Images were the first target because they affected two metrics at once.
- Compressed every above-the-fold image to WebP, each under 200 KB.
- Added explicit
widthandheightattributes on every<img>, so the browser reserves space before the file arrives. - Added
loading="lazy"to images below the fold andfetchpriority="high"to the LCP image.
Here is the before-and-after markup for the hero image:
<!-- Before -->
<img src="/uploads/hero-banner.png" alt="Viraa Professional team">
<!-- After -->
<img src="/uploads/hero-banner.webp"
alt="Viraa Professional team"
width="1600" height="900"
fetchpriority="high">
Impact: mobile LCP went from 6.2s to 3.4s and mobile CLS from 0.28 to 0.09. Roughly 70% of the eventual LCP improvement came from compressing five images. If you only have one afternoon for performance, spend it here.
Note what we did not do: we did not lazy-load the hero. Lazy-loading the LCP element is one of the most common self-inflicted wounds we see, because it tells the browser to delay the very image Google is timing.
Week 2: deferring JavaScript to fix INP
INP measures how quickly the page responds when someone taps, clicks or types. On mid-range phones, the usual culprit is JavaScript that occupies the main thread just when the user tries to interact.
- Loaded Google Analytics and Google Tag Manager with
defer. - Deferred all other third-party scripts, including the chat widget and analytics beacons, until the first user interaction.
- Removed three unused WordPress plugins whose scripts loaded on every page.
A simple pattern for loading a chat widget only after interaction:
<script>
['scroll','pointerdown','keydown'].forEach(function (evt) {
window.addEventListener(evt, loadChat, { once: true, passive: true });
});
function loadChat() {
if (window.chatLoaded) return;
window.chatLoaded = true;
var s = document.createElement('script');
s.src = 'https://chat.example.com/widget.js';
s.async = true;
document.body.appendChild(s);
}
</script>
Impact: mobile INP went from 418ms to 210ms, and total main-thread work dropped by about 40%. Close to the 200ms line but not over it yet.
Week 3: server response and caching
With images and scripts tamed, the remaining LCP delay was the server. Time to First Byte (TTFB) is not itself a Core Web Vital, but every millisecond of it is added to LCP.
- Enabled full-page caching with WP Rocket.
- Put Cloudflare (free plan) in front of the site with cache rules for HTML.
- Minified CSS and inlined the critical above-the-fold CSS.
Impact: TTFB dropped from 780ms to 190ms, and mobile LCP moved from 3.4s to 2.1s, inside the "good" band for the first time.
A word of caution on caching HTML at the edge: make sure logged-in pages, forms with nonces and anything personalised are excluded. A cache rule that serves one user's session to another is a far worse problem than a slow page.
Weeks 4 to 6: the last mile
The final stretch was about polishing the metrics that were close but not comfortably passing.
- Removed two render-blocking font imports and used
font-display: swapon the remaining fonts. - Found a heavy hero animation that fired on every page and restricted it to the homepage.
- Broke a long-running JavaScript task into smaller chunks scheduled with
requestIdleCallback, which brought INP comfortably under the threshold.
The final scorecard
| Metric | Mobile before | Mobile after | Desktop before | Desktop after |
|---|---|---|---|---|
| LCP | 6.2s | 2.1s | 3.9s | 1.4s |
| INP | 418ms | 168ms | 232ms | 98ms |
| CLS | 0.28 | 0.04 | 0.19 | 0.02 |
| PSI score | 32 | 91 | 58 | 97 |
Both mobile and desktop now pass all three Core Web Vitals thresholds. In the same window the overall RankStreet audit score rose from 43 to 71, with performance as the biggest lever.
Lessons from this Core Web Vitals case study
- Image weight comes first. Most of the LCP gain came from five images. It is the cheapest fix with the largest effect on most sites we audit.
- Dimension attributes fix most CLS. On WordPress sites, the majority of layout shift comes from images without
widthandheight. - Third-party scripts are the usual INP problem. Audit chat widgets, heatmaps and tag managers ruthlessly. Defer what you need; remove what you do not.
- Edge caching is a big lever for small budgets. A free Cloudflare plan in front of modest hosting cut TTFB from 780ms to 190ms here.
- Lab scores are not the finish line. PageSpeed's lab score is a diagnostic. Google ranks on field data from real Chrome users, which updates over a rolling 28-day window, so expect a lag between shipping a fix and seeing it in Search Console.
What we would do differently next time
Hindsight is useful, so here is what we would change if we ran this project again.
- Set a performance budget on day one. Agreeing limits up front, for example a maximum image weight above the fold and a cap on third-party scripts, would have stopped the problems accumulating in the first place. Budgets turn performance from a project into a habit.
- Test on a real mid-range Android phone. Desktop DevTools throttling is a useful approximation, but a physical device used by actual customers reveals interaction delays that simulations understate.
- Agree a plugin policy with the content team. Three of the scripts we removed came from plugins installed for one-off tasks and never uninstalled. A simple rule, that every plugin needs an owner and a reason, prevents most of this.
A step-by-step checklist you can reuse
- Run a free RankStreet audit on your three most important pages and note LCP, INP and CLS for mobile.
- Identify the LCP element on each page (PageSpeed Insights names it). Compress it, add dimensions and
fetchpriority="high". - Add
widthandheightto every image and reserve space for embeds and ads. - List every third-party script. Defer, delay until interaction, or delete.
- Check TTFB. If it is above roughly 600ms, add page caching and a CDN.
- Re-audit, then watch Search Console's Core Web Vitals report for field data over the following four weeks.
For the content and structured-data side of an audit, see our free website audit guide, and for a site where performance and trust work happened together, read the fundabroad.com case study.
If your site is failing Core Web Vitals and you would rather a senior team fix it, talk to Digistreet Media. This is the playbook we used here.
Frequently asked questions
What are the Core Web Vitals thresholds in 2026?
Google's "good" thresholds are LCP at or below 2.5 seconds, INP at or below 200 milliseconds and CLS at or below 0.1, measured at the 75th percentile of real page loads. INP replaced First Input Delay as the responsiveness metric in March 2024.
What fixed the most in this Core Web Vitals case study?
Image work. Compressing above-the-fold images to WebP, adding dimension attributes and prioritising the LCP image cut mobile LCP from 6.2s to 3.4s and CLS from 0.28 to 0.09 in the first week.
Why does PageSpeed Insights show a pass but Search Console still shows failing URLs?
PageSpeed's lab test runs once in a simulated environment, while Search Console reports field data collected from real Chrome users over the previous 28 days. After a fix, field data takes several weeks to catch up.
Do Core Web Vitals directly improve rankings?
They are part of Google's page experience signals, which Google describes as one factor among many. Relevance and content quality matter more, but in close contests a faster, more stable page has an edge, and it keeps more visitors either way.
Can I fix Core Web Vitals on WordPress without a developer?
Many fixes, such as image compression, caching plugins and removing unused plugins, need no code. Deferring third-party scripts and breaking up long JavaScript tasks usually benefit from a developer's help.
Ready to put this into practice?
Run a free 60-point audit on any URL and get a prioritised fix list in under a minute.
About the publisher
Built by Digistreet Media
RankStreet is built and operated by Digistreet Media — a digital marketing and SEO agency with 13+ years across Finance, FMCG, Real Estate, B2B, Automobiles, Fashion, SaaS, Healthcare and Commerce. Prefer a senior team to run the audit and the fixes for you? Talk to Digistreet.
