Core Web Vitals have been a Google ranking signal since 2021, but in 2026 the stakes are higher: more sites have achieved Good scores, making the competitive gap between Good and Poor scores more decisive in rankings. With INP replacing FID in March 2024, many sites that had Good FID scores are now discovering they fail INP. This checklist covers every optimization you need to audit and implement to hit Good scores across all three Core Web Vitals in 2026.
Understanding Core Web Vitals in 2026
Three metrics comprise Core Web Vitals:
- LCP (Largest Contentful Paint): When the largest visible element renders. Measures loading performance.
- INP (Interaction to Next Paint): Latency of user interactions (clicks, taps, keyboard). Measures responsiveness.
- CLS (Cumulative Layout Shift): Visual instability — elements jumping around. Measures visual stability.
Google measures all three at the 75th percentile of real-user field data collected via Chrome User Experience Report (CrUX). This means 25% of your users can have Poor scores without affecting your official classification — but those users still experience poor performance, which affects behavior and conversion.
Part 1: LCP Optimization Checklist
Target: LCP under 2.5s at P75 (competitive target: under 1.5s)
Identify Your LCP Element
- ☐ Use PageSpeed Insights or Chrome DevTools to identify the actual LCP element
- ☐ Verify LCP element is the same across desktop and mobile (they often differ)
- ☐ Check CrUX data in Google Search Console Core Web Vitals report (field data, not lab)
LCP Image Optimization
- ☐ Add
fetchpriority="high"to LCP image element - ☐ Add
<link rel="preload" as="image" href="...">in<head>for LCP image - ☐ Remove
loading="lazy"from LCP image (never lazy-load above-the-fold images) - ☐ Convert LCP image to AVIF (with WebP fallback) using
<picture>element - ☐ Implement responsive images with correct
srcsetandsizesattributes - ☐ Set explicit
widthandheightattributes to prevent CLS during load - ☐ Serve LCP image from CDN edge nodes (not origin server)
- ☐ Move LCP image from CSS
background-imageto HTML<img>tag if applicable
Server and Network Optimization
- ☐ Achieve TTFB under 800ms at P75 (check Google Search Console TTFB report)
- ☐ Enable edge/CDN caching for HTML responses (target <100ms TTFB with cache hit)
- ☐ Enable HTTP/3 on CDN configuration
- ☐ Implement Early Hints (103 status) for LCP preload if TTFB > 200ms
- ☐ Enable Brotli compression (better ratio than gzip)
Critical Rendering Path
- ☐ Inline critical CSS (above-the-fold styles) in
<head> - ☐ Async-load non-critical CSS via
rel="preload"+ onload pattern - ☐ Mark non-critical scripts as
asyncordefer - ☐ Add
preconnecthints for critical third-party origins (font CDN, image CDN) - ☐ Audit and remove unused CSS (PurgeCSS, WP Rocket “Remove Unused CSS”)
Third-Party Script Management
- ☐ Audit Google Tag Manager container (remove unused/zombie tags)
- ☐ Implement facade pattern for heavy third-party widgets (live chat, YouTube embeds)
- ☐ Delay non-critical third-party scripts until after user interaction or page load
- ☐ Consider Partytown for analytics scripts (off-main-thread execution)
Part 2: INP Optimization Checklist
Target: INP under 200ms at P75 (competitive target: under 100ms)
Understand INP Measurement
- ☐ Identify slow interactions via Chrome DevTools Performance panel (interaction tracing)
- ☐ Use Web Vitals Chrome Extension to capture INP on real user interactions
- ☐ Check CrUX INP distribution in Google Search Console
- ☐ Identify which interaction types (click, keydown, tap) are worst
Main Thread Optimization
- ☐ Break long tasks into smaller chunks (tasks over 50ms block the main thread)
- ☐ Use
scheduler.yield()orsetTimeout(0)to yield between task chunks - ☐ Move heavy computation to Web Workers (background thread)
- ☐ Audit JavaScript bundle size — large bundles take longer to parse, consuming main thread time
- ☐ Implement code splitting — only load JavaScript needed for current page/component
Event Handler Optimization
- ☐ Profile event handler execution time in Chrome DevTools
- ☐ Remove unnecessary work from click handlers (defer non-critical work)
- ☐ Avoid synchronous layout reads in event handlers (avoid forced reflow)
- ☐ Debounce expensive event handlers (scroll, resize, input)
- ☐ Use event delegation rather than attaching handlers to many elements
React/Framework-Specific INP
- ☐ Profile React renders with React DevTools Profiler
- ☐ Implement React.memo() to prevent unnecessary re-renders
- ☐ Use useMemo/useCallback to stabilize expensive computations and callbacks
- ☐ Enable React 18 concurrent features (useTransition for non-urgent state updates)
- ☐ Audit useEffect hooks for unnecessary execution on every render
- ☐ For Next.js: enable Turbopack; use Server Components to reduce client-side JavaScript
Animation and CSS Transitions
- ☐ Animate only GPU-composited properties:
transformandopacity - ☐ Avoid animating
width,height,margin,padding(trigger layout) - ☐ Use
will-change: transformto hint browser to promote element to its own layer - ☐ Prefer CSS animations over JavaScript animations for simple transitions
Part 3: CLS Optimization Checklist
Target: CLS under 0.1 at P75 (competitive target: under 0.05)
Image and Media Dimensions
- ☐ Set explicit
widthandheighton all images (browser computes aspect ratio and reserves space) - ☐ Set explicit dimensions on video elements
- ☐ Use CSS aspect-ratio for responsive images where explicit sizes aren’t practical
- ☐ Never use images without dimensions in content areas
Font Loading
- ☐ Use
font-display: optionalfor fonts not critical to above-the-fold content - ☐ Preload critical web fonts using
<link rel="preload" as="font" crossorigin> - ☐ Define font fallback metrics using
size-adjust,ascent-override,descent-overrideto minimize FOUT shift - ☐ Consider system font stack for headings if custom font creates significant layout shift
Ad Slots and Dynamic Content
- ☐ Reserve space for ad slots with minimum height containers (
min-heightCSS) - ☐ Never insert content above existing content after load unless triggered by user interaction
- ☐ Anchor dynamic banners/notifications to bottom of viewport, not top
- ☐ Reserve space for cookie consent banners and GDPR modals
Embedded Content
- ☐ Set fixed dimensions on iframe embeds (YouTube, Google Maps, social posts)
- ☐ Use placeholder containers with correct aspect ratio while embeds load
- ☐ Lazy-load below-fold embeds to prevent layout shifts in off-screen areas
JavaScript-Driven Shifts
- ☐ Identify shift-causing JavaScript via Layout Shift Attributor Chrome extension
- ☐ Delay dynamic UI elements (popups, sticky headers, banners) to avoid shifts during initial load
- ☐ Use CSS containment (
contain: layout) for independently updating sections
Measurement and Monitoring Checklist
- ☐ Set up Google Search Console Core Web Vitals report (field data baseline)
- ☐ Configure PageSpeed Insights monitoring (lab data benchmarks)
- ☐ Install Web Vitals Chrome Extension for manual page testing
- ☐ Set up Lighthouse CI in CI/CD pipeline (catch regressions before deploy)
- ☐ Configure RUM (Real User Monitoring): web-vitals.js library → analytics pipeline
- ☐ Set up performance budget alerts (alert when P75 LCP exceeds threshold)
- ☐ Review CrUX data monthly (field data is 28-day rolling; improvements take weeks to show)
Common CWV Failure Patterns and Fixes
LCP fails on mobile but passes on desktop: Mobile images may not have proper srcset, or mobile TTFB is slower due to cellular network latency. Verify mobile-specific optimizations and check mobile CrUX separately.
INP passes in lab but fails in field: INP is highly sensitive to CPU performance. Lab tests use fast hardware; real users on budget Android devices experience much worse INP. Test on throttled devices (Chrome DevTools 4x CPU slowdown) and real low-end mobile hardware.
CLS score is zero in Lighthouse but fails in field: Many layout shifts are triggered by user interaction or occur after initial load — Lighthouse’s lab test often misses them. Use the Web Vitals extension to manually interact with pages and observe real CLS.
Third-party scripts causing all three metrics to fail: Run a Lighthouse trace with third-party scripts blocked to isolate their impact. Use Request Blocking in Chrome DevTools to simulate removal of specific scripts. Sometimes a single analytics or chat script accounts for 80% of performance degradation.
Conclusion
Achieving Good Core Web Vitals in 2026 requires systematic optimization across all three metrics, measured with real field data rather than lab scores. Use this checklist as your audit starting point — identify which items are failing in your CrUX data, prioritize fixes by impact, and implement iteratively. The performance gains compound: faster LCP improves user experience; better INP increases engagement; lower CLS reduces frustration. Combined, they create measurable improvements in conversion rate and search ranking that justify the engineering investment.