Core Web Vitals: A Practical Checklist for Developers

1/25/2026Forgeora Team
Core Web Vitals: A Practical Checklist for Developers

Tangible steps to measure and improve LCP, FID/INP, and CLS to boost rankings and user experience.

Core Web Vitals are Google's framework for measuring user experience quantitatively. They are ranking signals in Google Search and, more importantly, they directly correlate with business outcomes: faster LCP improves conversion rates, lower INP reduces task abandonment, stable CLS prevents accidental clicks that frustrate users. Getting them right is both an SEO and a product quality imperative. ## Understanding the Three Metrics **Largest Contentful Paint (LCP)** measures how long it takes for the largest content element visible in the viewport—typically a hero image, banner, or large text block—to fully render. Good LCP is under 2.5 seconds. LCP is primarily bottlenecked by network speed (resource load times) and render-blocking resources. **Interaction to Next Paint (INP)** replaced First Input Delay (FID) in 2024. It measures the latency of all page interactions (clicks, taps, keyboard input) throughout the page lifecycle, not just the first. Good INP is under 200ms. INP is primarily bottlenecked by long JavaScript tasks on the main thread that prevent the browser from responding to user input. **Cumulative Layout Shift (CLS)** measures unexpected visual movement of content during page load. Good CLS is below 0.1. CLS is caused by images without explicit dimensions, dynamically injected content above existing content, web fonts that cause text reflow, and ads or embeds with unknown dimensions. ## LCP Optimization Checklist ### 1. Identify Your LCP Element Use Chrome DevTools Performance panel or the Chrome User Experience Report (CrUX) to identify the LCP element. For most content sites, it's the hero image. For text-heavy pages, it may be the largest text block. ### 2. Preload the LCP Image If the LCP element is an image, add a `<link rel="preload">` in the `<head>`: ```html <link rel="preload" as="image" href="/hero.webp" fetchpriority="high"> ``` In Next.js, use `priority` on the hero `<Image>` component. ### 3. Optimize Image Format and Size - Serve WebP or AVIF instead of JPEG/PNG (20-50% smaller at same quality) - Serve correctly-sized images for the user's viewport—avoid serving a 4000px image for a 400px display slot - Use `srcset` and `sizes` attributes for responsive images ### 4. Eliminate Render-Blocking Resources Scripts with `<script src="">` without `async` or `defer` block HTML parsing. Audit with Coverage panel in DevTools and add `defer` to non-critical scripts. Inline critical CSS for above-the-fold content. ### 5. Optimize Time to First Byte (TTFB) LCP can't start until the first byte arrives. Improve TTFB by using CDNs for static assets, caching SSR responses at the edge, and optimizing database queries that block server response. ## INP Optimization Checklist ### 1. Break Up Long Tasks Any JavaScript task that runs for more than 50ms on the main thread can delay input response. Use Chrome DevTools' Performance panel to identify long tasks. Break them up with `scheduler.yield()`: ```javascript async function processLargeDataset(items) { for (let i = 0; i < items.length; i++) { processItem(items[i]); if (i % 100 === 0) { await scheduler.yield(); // yield to browser between batches } } } ``` ### 2. Move Heavy Work to Web Workers Parsing large JSON responses, running complex calculations, and processing data can all be offloaded to Web Workers, keeping the main thread free for user interactions. ### 3. Defer Non-Critical JavaScript Third-party scripts (analytics, chat widgets, social embeds) are common sources of main-thread contention. Load them with `loading="lazy"` or inject them after the first user interaction using the "facade" pattern. ### 4. Optimize Event Handlers Heavy computations directly in click handlers block the response. Debounce expensive handlers, use `requestAnimationFrame` for visual updates triggered by events, and avoid forced layout/reflow in handlers (accessing `offsetWidth`, `scrollTop`, etc.). ## CLS Optimization Checklist ### 1. Always Specify Image Dimensions Every `<img>` element should have explicit `width` and `height` attributes. This allows the browser to reserve the correct space before the image loads, preventing layout shift. ### 2. Reserve Space for Dynamic Content If you inject banners, cookie notices, or recommendations above existing content, reserve their space with a minimum-height container—even if it's empty initially—so content doesn't jump when they appear. ### 3. Preload Web Fonts and Use `font-display: optional` Web fonts cause FOUT (Flash of Unstyled Text) and FOIT (Flash of Invisible Text), both of which can cause CLS. Preload critical fonts and use `font-display: swap` or `font-display: optional` depending on your tolerance for FOUT. ### 4. Avoid Inserting Content Above Existing Content Never dynamically insert elements above the fold that push down existing content. If you must add elements (live notifications, banners), append them below existing content or use fixed/absolute positioning that doesn't affect document flow. ## Field Data vs Lab Data Lighthouse runs in a controlled lab environment. Field data from real users (via CrUX) often differs significantly—real networks are slower, real devices more varied, and real pages have third-party scripts and dynamic content that lab tests don't capture. Use both: Lighthouse for fast development feedback, CrUX data in Google Search Console for understanding real user experience. Optimize for field data; lab data is a proxy.