Dev Tool

Fix Core Web Vitals — LCP, INP and CLS

Improve LCP, INP, and CLS — step-by-step fixes for slow websites (includes tools for minification and image optimization)

AllOmnitools Editorial Team

Core Web Vitals (2024→2025 thresholds)

MetricGoodNeeds ImprovementPoor
LCP
Largest Contentful Paint
= 2.5s2.5→4s> 4s
INP
Interaction to Next Paint
= 200ms200→500ms> 500ms
CLS
Cumulative Layout Shift
= 0.10.1→0.25> 0.25

Test your site: PageSpeed Insightsweb.dev/measure — Chrome DevTools ? Lighthouse panel

LCP — Largest Contentful Paint

Measures when the largest content element becomes visible. Poor LCP means slow loading hero image, render-blocking CSS/JS, or slow server response.

LCP Server response time (TTFB) is slow

TTFB (Time to First Byte) > 600ms hurts LCP. Often caused by slow backend, unoptimized database queries, or no caching.

  1. 1Enable server-side caching (Redis, Varnish, CDN edge cache).
  2. 2Optimize database queries — add indexes, reduce N+1 queries.
  3. 3Use a CDN (Cloudflare, Fastly, Vercel edge) to serve static assets closer to users.
  4. 4Upgrade hosting if shared hosting is the bottleneck.
TTFB goal: under 200ms for fast sites. Use webpagetest.org to break down TTFB.
LCP Render-blocking CSS or JavaScript

Browser can't paint LCP element until blocking CSS/JS loads and executes.

  1. 1Inline critical CSS (above-the-fold styles) directly in <head>.
<style>/* critical CSS: navbar, hero bg */</style>
  1. 2Load non-critical CSS asynchronously:
<link rel="preload" as="style" href="non-critical.css" onload="this.rel='stylesheet'"><noscript><link rel="stylesheet" href="non-critical.css"></noscript>
  1. 3Defer non-critical JavaScript: defer or async attribute.
<script src="analytics.js" defer></script>
Use our CSS Minifier to reduce CSS file size. For JS, use JS Minifier.
LCP Large, unoptimized hero image / video

LCP element is often a large image or video. If not optimized, it takes too long to download and render.

  1. 1Compress and resize to exact dimensions needed. Use modern formats:
<picture> <source srcset="hero.avif" type="image/avif"> <source srcset="hero.webp" type="image/webp"> <img src="hero.jpg" width="1200" height="600" alt="..." loading="eager"> </picture>
  1. 2Dimensions: don't rely on CSS scaling. Ship an image close to its display size.
  2. 3Preload LCP image:
<link rel="preload" as="image" href="hero.webp" imagesrcset="hero-400.webp 400w, hero-800.webp 800w, hero-1200.webp 1200w" imagesizes="100vw">
  1. 4Use loading="eager" for LCP image (default for above-the-fold), loading="lazy" for below-fold.
Use our Image Resizer to resize and optimize images. GIF Optimizer for animated content.

Target widths for responsive: 400, 800, 1200, 1600, 2000px. WebP is ~30% smaller than JPEG; AVIF is even smaller.
LCP No preconnect or DNS prefetch for critical origins

Third-party resources (CDNs, fonts, APIs) add DNS lookup, TCP, TLS handshake delays. preconnect warms up connections early.

<link rel="preconnect" href="https://fonts.googleapis.com"> <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin> <link rel="dns-prefetch" href="https://cdn.example.com">
Preconnect to critical third parties: Google Fonts, CDNs, analytics (if you must). Don't overuse — each connection costs CPU/memory. crossorigin needed for fonts.
INP — Interaction to Next Paint (replaced FID)

Measures responsiveness: time from user interaction (click, tap, keypress) to next paint. Poor INP means UI feels laggy. Often caused by long JavaScript tasks blocking the main thread.

INP Long main-thread tasks block responsiveness

JavaScript running > 50ms delays paint after interaction. Break up heavy work or move off-main-thread.

  1. 1Break large tasks into chunks with setTimeout or requestIdleCallback:
function processChunk(items) { const chunk = items.splice(0, 50); chunk.forEach(processItem); if (items.length) { setTimeout(() => processChunk(items), 0); } }
  1. 2Move expensive work to a Web Worker:
// main.js const worker = new Worker('worker.js'); worker.postMessage(data); worker.onmessage = (e) => { /* result */ };
// worker.js self.onmessage = (e) => { const result = heavyCalc(e.data); self.postMessage(result); };
  1. 3Debounce or throttle frequent event handlers (scroll, resize, mousemove).
Use async/await with setTimeout or requestAnimationFrame to yield to the browser. Chrome DevTools ? Performance panel identifies longest tasks.
INP JavaScript bundle too large

Large JS downloads, parses, and executes slowly, delaying interaction handlers. Code-split, tree-shake, and minify.

  1. 1Code-split: load only what's needed for current page.
import('./heavy-module.js').then(module => { module.init(); });
  1. 2Minify all JS — use our JS Minifier or build tool (Terser, esbuild).
  1. 3Lazy-load non-critical scripts with defer/async or after DOMContentLoaded.
  1. 4Use requestIdleCallback to schedule low-priority work during idle time.
Don't block the main thread. Any single task > 50ms risks poor INP. If a function takes 200ms, split it into four 50ms chunks with setTimeout or queueMicrotask.
CLS — Cumulative Layout Shift

Measures visual stability. Elements moving around unexpectedly cause poor CLS. Usually images without dimensions, dynamic content insertion, or fonts that shift text.

CLS Images without width/height attributes

Browser doesn't know image aspect ratio until it loads ? layout shifts when image renders.

<!-- Bad — no dimensions --> <img src="photo.jpg" alt="...">
<!-- Good — explicit width & height --> <img src="photo.jpg" width="800" height="600" alt="...">
<!-- For responsive: use CSS aspect-ratio --> <img src="photo.jpg" style="aspect-ratio: 4/3; width: 100%; height: auto;">
If you don't know exact dimensions, compute aspect ratio. Example: 1200x600 ? aspect-ratio: 2/1. Modern CSS: aspect-ratio. Legacy: padding-bottom hack.
CLS Dynamic content inserted above existing elements

Banners, notifications, or ads that appear after page load push content down. Reserve space in advance.

  1. 1Reserve fixed-height container for dynamic content:
<div id="banner-container" style="min-height: 80px;"></div>
  1. 2Or inject content off-screen (fixed/absolute positioning) then animate in without affecting flow.
  1. 3For ads, use aspect-ratio to reserve ad slot dimensions before network response.
CLS whitelist: user-initiated interactions (clicks, scrolls) don't count. But auto-playing videos, cookie banners, or notification popups that appear immediately count toward CLS.
CLS Font loading causes FOIT / FOUT layout shift

Web fonts load after system font fallback. Switch causes text size/width to shift (FOUT) or invisible (FOIT).

  1. 1Use font-display: swap in @font-face:
@font-face { font-family: 'MyFont'; src: url('myfont.woff2') format('woff2'); font-display: swap; }
  1. 2Preload key fonts to avoid late discovery:
<link rel="preload" as="font" href="/fonts/inter.woff2" type="font/woff2" crossorigin>
  1. 3For hero text, consider system font stack to avoid any FOIT/FOUT.
System fonts: font-family: system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;. Zero CLS from font loading.

What Core Web Vitals are and why they matter for rankings

Core Web Vitals are three page experience metrics Google uses as a ranking signal: LCP (Largest Contentful Paint — how fast the main content loads), INP (Interaction to Next Paint — how fast the page responds to clicks and taps), and CLS (Cumulative Layout Shift — how much the page jumps around while loading). Poor scores don't tank rankings overnight, but they're a tiebreaker between pages with similar content quality.

LCP (should be under 2.5 seconds)

  • Add fetchpriority="high" to your hero image — tells the browser to load it first
  • Preload the LCP image<link rel="preload" as="image" href="hero.webp"> in the <head>
  • Serve images in WebP or AVIF — 30—50% smaller than JPEG at the same quality
  • Use a CDN — reduces TTFB which delays when LCP can even start
  • Remove render-blocking CSS — inline critical CSS, defer everything else

INP (should be under 200ms)

  • Break up long tasks — anything over 50ms blocking the main thread hurts INP. Use setTimeout or scheduler.yield() to yield between tasks
  • Reduce JavaScript execution time — audit with Chrome DevTools Performance panel, look for long tasks
  • Avoid heavy event listeners — especially on scroll and resize
  • Defer non-critical JS — use defer or async on script tags

CLS (should be under 0.1)

  • Set width and height on images — the browser needs dimensions to reserve space before the image loads
  • Reserve space for ads and embeds — use min-height or aspect-ratio containers
  • Avoid injecting content above existing content — banners, cookie notices, and dynamic elements that push content down cause CLS
  • Use font-display: optional — prevents text from jumping when a web font loads

How to measure your Core Web Vitals

PageSpeed Insights (pagespeed.web.dev) gives you both lab data (simulated) and field data (real users from Chrome UX Report). The field data is what Google actually uses for ranking. Chrome DevTools Lighthouse gives you lab data only. Use Search Console → Core Web Vitals report for aggregate real-user data across your whole site.

Complete Developer Toolkit

Improving Core Web Vitals requires optimizing every layer of your web stack. The two highest-impact tools for LCP and INP are our CSS minifier and JS minifier — smaller CSS unblocks rendering sooner for better LCP, and smaller JS reduces main thread work for better INP. For image-heavy pages, our image tools make the biggest difference: use the image resizer to serve images at display dimensions, and the image to WebP converter to reduce image payload sizes by 25—35%.

For CLS issues caused by layout shifts from late-loading content, our SVG path visualizer helps you inline critical SVG icons directly in HTML so they render immediately without a network request. Our Base64 encoder converts small critical images to inline data URIs, eliminating render-blocking image requests. The diff checker is useful for comparing Lighthouse reports before and after optimizations to quantify improvements. When your performance issues stem from slow API responses, our API response simulator lets you test UI behavior with instant mock data. Our CORS error guide addresses the network errors that can block critical resource loading and tank your LCP score.

FAQ

Yes, as a tiebreaker. Google confirmed they're a ranking signal, but content relevance and quality still dominate. A page with great content and poor vitals will usually outrank a page with poor content and perfect vitals. But between two equal pages, vitals can be the differentiator.