Skip to content
All articles
PerformanceWeb Vitals

The Full-Stack Engineer's Guide to Core Web Vitals

Practical tips from production — not theory, not docs rewrites, just what actually moved the needle.

8 January 202610 min read

Why Most Web Vitals Advice Falls Short

I've read every Google blog post on Core Web Vitals. Most of them tell you what the metrics are and why they matter. Very few tell you how to actually fix them in a real codebase with a dozen third-party scripts, a legacy CSS pipeline, and a product team that ships twice a week.

Over the past five years I've optimized Web Vitals at three different companies — Mamaearth, CARS24, and Flipkart. Each time the bottlenecks were wildly different, but the debugging approach was the same. This article is the playbook I wish I'd had on day one.

If you walk away with one thing, let it be this: measuring in the lab is necessary but insufficient. Real-user monitoring is where you find the truth, and the truth is usually uglier than Lighthouse suggests.

INP: The Metric Nobody Talks About Enough

At CARS24 we had an INP problem that didn't show up in any lab test. Our car listing page looked fast — Lighthouse was green across the board. But field data told a different story. Users on mid-range Android phones were experiencing 400ms+ delays on filter interactions.

The root cause was a cascade of React re-renders triggered by our filter state management. Every filter change recalculated a derived price range, which triggered a context update, which re-rendered 200+ car cards. We fixed it by memoizing the derived computation and breaking the context into two separate providers — one for filter state, one for display state.

INP dropped from 380ms to 90ms. The lesson: INP is almost never about one slow event handler. It is about the downstream work that event handler triggers. Profile the entire chain, not just the click.

TBT and the Third-Party Script Problem

At Mamaearth, our Total Blocking Time was north of 1200ms on mobile. Half of that was our own JavaScript. The other half was analytics, marketing pixels, chatbots, and A/B testing libraries — tools the business considered non-negotiable.

We couldn't remove them, so we deferred them. I wrote a script loader that used requestIdleCallback to load third-party scripts only after the main thread was idle. For scripts that needed to run on page load, we used web workers where possible and facade patterns for things like the chat widget.

TBT dropped to 400ms. It's not perfect, but it was the difference between a failing and passing Core Web Vitals assessment. The key insight is that you don't need to eliminate third-party scripts — you need to make them yield to your critical path.

LCP: It Is Almost Always an Image

In my experience, LCP issues are the most straightforward to fix. Nine times out of ten, your LCP element is a hero image or a banner, and the fix is some combination of proper sizing, format optimization, and preloading.

At Flipkart, we shaved 800ms off LCP by switching hero images to AVIF with WebP fallback and adding a preload link in the document head. We also moved from client-side image rendering to server-rendering the img tag with explicit width and height to eliminate layout shifts.

The one non-obvious trick: if your LCP element is text rendered with a custom font, the fix is font-display: optional combined with a preloaded font file. We used this at CARS24 for the car detail page headline and it eliminated the flash of invisible text entirely.

CLS: Death by a Thousand Shifts

CLS is the metric where I see teams make the most mistakes. They fix one layout shift, declare victory, and then a product change introduces three more. The fix isn't one-time — it's systemic.

What works: enforce explicit dimensions on all media elements via an ESLint rule, use CSS aspect-ratio for responsive containers, and reserve space for dynamic content like ads or lazy-loaded modules with min-height placeholders. At CARS24 we added a CLS budget to our CI pipeline that failed the build if any page exceeded 0.1. It was annoying at first, but it forced the team to think about layout stability during development, not after.

Building a Web Vitals Culture

The hardest part of Web Vitals work isn't the technical fixes. It's convincing your team that performance is a feature, not a chore. I've found that the best way to do this is to connect metrics to business outcomes.

At Mamaearth, we correlated our LCP improvements with a measurable increase in add-to-cart rate on collection pages. That single data point got performance onto the product roadmap permanently. At CARS24, we showed that pages with good INP had 15% higher lead conversion than pages with poor INP.

My advice: instrument everything, build dashboards that product managers can read, and present performance work in business language. Nobody cares that you reduced TBT by 600ms. Everyone cares that you improved conversion by 8%.

Found this useful? I write about engineering, performance, and career growth.