Core Web Vitals Optimization: A Frontend Developer's Practical Guide for 2026
Core Web Vitals are not just metrics — they are Google's page experience ranking signals. Every frontend developer needs to understand and optimize for LCP, INP, and CLS. Here is my practical guide, based on optimizing real-world applications that achieved 95+ Lighthouse scores.
LCP: Largest Contentful Paint
LCP measures when the largest content element (hero image, heading, or video poster) becomes visible. Google considers LCP under 2.5 seconds as "good."
On the Electron Enterprise project, I reduced LCP from 3.2s to 1.1s through four specific interventions:
- Preloaded the hero image with
fetchpriority="high"on the LCP element - Inlined critical CSS — the above-fold styles are inlined in the head, eliminating a render-blocking CSS request
- Deferred non-critical JavaScript — analytics, chat widgets, and third-party scripts load after the page is interactive
- Used server-rendered HTML — Next.js Server Components deliver fully rendered content, eliminating client-side rendering delays
<img
src="/hero.webp"
alt="Bhavya Panchal — Frontend Developer"
fetchpriority="high"
width="1200"
height="630"
/>
INP: Interaction to Next Paint
INP replaced First Input Delay (FID) in March 2024. It measures the latency of all user interactions throughout the page lifecycle. INP under 200ms is considered "good."
Common INP problems I encounter in my performance optimization audits:
- Expensive event handlers — onClick handlers that trigger state updates across large component trees
- Main thread blocking — synchronous data processing during user interactions
- Large component re-renders — state changes that cascade through unoptimised component trees
The fix: break up long tasks using requestIdleCallback or scheduler.postTask, memoize expensive computations, and use React's useTransition for non-urgent updates:
const [isPending, startTransition] = useTransition();
function handleFilterChange(value: string) {
startTransition(() => {
setFilteredItems(filterItems(items, value));
});
}
CLS: Cumulative Layout Shift
CLS measures visual stability. Pages should maintain a CLS of 0.1 or less. On the Content Platform project, I achieved zero CLS through:
- Explicit dimensions on all images and videos — width and height attributes on every media element
- Font preloading with font-display: swap — prevents text from shifting when fonts load
- Reserved space for dynamic content — ad slots, banners, and injected widgets have min-height defined
- Avoiding layout-inducing animations — using CSS transform instead of properties that trigger layout (top, left, width)
Measuring in Production
Lab data (Lighthouse) tells you what is possible. Field data (CrUX, RUM) tells you what users actually experience. I set up Real User Monitoring with the web-vitals library:
import { onLCP, onINP, onCLS } from 'web-vitals';
function sendToAnalytics({ name, value, id }) {
gtag('event', name, {
value: Math.round(name === 'CLS' ? value * 1000 : value),
metric_id: id,
});
}
onCLS(sendToAnalytics);
onINP(sendToAnalytics);
onLCP(sendToAnalytics);
Key Takeaways
- LCP optimization: preload hero images, inline critical CSS, defer non-critical JS, use SSR
- INP optimization: break up long tasks, memoize computations, use transitions for non-urgent updates
- CLS optimization: explicit dimensions on all media, font preloading, reserved space for dynamic content
- Measure in production — lab data is not enough
Core Web Vitals optimization is central to my performance optimization service. If your application is struggling with LCP, INP, or CLS, a systematic audit is the fastest path to improvement.
Written by Bhavya Panchal — Frontend Developer & UI Engineer
WORK WITH ME