Core Web Vitals Optimization Checklist | LCP, CLS & INP in Production
이 글의 핵심
Treat LCP as largest paint path, CLS as layout reservation, and INP as interaction latency—measure with field data first, then lab tools for regressions.
Introduction
Core Web Vitals summarize loading (LCP), responsiveness (INP, formerly FID), and visual stability (CLS) in user-perceived terms. Web Vitals / LCP / CLS improvement is not “gaming a score”—it is making the largest paint faster, layouts less jumpy, and inputs more responsive.
This article assumes 2026-era Chrome guidance with INP as the interaction metric, and lists repeatable fixes for images, fonts, and third-party scripts—framework-agnostic principles plus patterns common in Next.js stacks.
After reading this post
- You can find LCP candidates and tune resource priority
- You can reduce common CLS causes (images, fonts, ads, dynamic inserts)
- You can inspect INP from main-thread and event-handler angles
Table of contents
- Concepts
- Hands-on implementation
- Advanced usage
- Performance comparison
- Real-world cases
- Troubleshooting
- Conclusion
Concepts
One-line summary
| Metric | Meaning | Good direction (rough guide) |
|---|---|---|
| LCP (Largest Contentful Paint) | When the largest content in the viewport paints | Faster (often ≤2.5s target) |
| CLS (Cumulative Layout Shift) | Layout movement during load | Lower (often ≤0.1) |
| INP (Interaction to Next Paint) | Delay from interaction to next paint | Lower (often ~200ms target) |
Thresholds are guidelines—segment by site, region, and device. Prefer field data (PageSpeed Insights, CrUX, RUM).
Why LCP and CLS tie to SEO and perceived quality
Search engines weigh user experience signals alongside content quality. Slow LCP hurts first impression; high CLS hurts clicks and trust. INP matters especially for SPAs and heavy widgets.
Hands-on implementation
LCP improvement sequence
-
Identify the LCP element
Chrome DevTools → Performance / Lighthouse → LCP element (often hero image or large text). -
Shorten discovery path
Ensure hero assets are requested from early HTML (SSR/static) and trim redirect chains. -
Prioritize
Usefetchpriority="high"on the true LCP image when appropriate; preload only when it really is LCP.
<img
src="/hero.webp"
alt="..."
width="1200"
height="630"
fetchpriority="high"
decoding="async"
/>
-
Format and size
WebP/AVIF,srcset/sizes, and resolutions matching display size. -
TTFB
Slow server, edge cache, or DB caps LCP ceiling—optimize App Router/API latency in tandem.
CLS improvement sequence
- Reserve space for images and video
Usewidth/heightoraspect-ratio.
<div class="aspect-video w-full max-w-3xl">
<img class="h-full w-full object-cover" src="..." alt="" width="1280" height="720" />
</div>
-
Web fonts
Pairfont-display: swapwith fallback metric tuning (size-adjust, …) to reduce swap jumps. -
Dynamic inserts
Ads, banners, cookie bars—reserve height or use skeletons. -
Animations
Prefertransform/opacityinstead of properties that shift layout.
INP improvement sequence
-
Split long tasks
Avoid >50ms main-thread blocks; move heavy work to workers or chunked scheduling. -
Event handlers
Avoid synchronous huge DOM updates or JSON parsing on click. -
Third parties
Profile tag managers and chat widgets—they often dominate main-thread time.
button.addEventListener('click', () => {
requestAnimationFrame(() => {
// heavy DOM updates
});
});
Advanced usage
- Speculation Rules API: Prefetch next navigations—balance benefit vs bandwidth/cache pressure.
- Critical CSS: Inline minimal above-the-fold CSS—factor maintenance cost in your build pipeline.
- RUM: Track LCP/CLS/INP percentiles by page, country, and device for regression alerts.
Performance comparison
| Approach | High impact when | Watch out |
|---|---|---|
| Image optimization | Hero- and thumbnail-heavy sites | Over-compressing quality |
| Font subsetting + preload | Custom-font LCP | Preload starvation of other assets |
| SSR / caching | TTFB-bound LCP | Stale dynamic data—design freshness |
| Deferred third parties | INP / TBT issues | Broken features if load order is wrong |
Real-world cases
- Marketing landing: WebP hero + explicit dimensions improved LCP ~30%; fixed-height ad slots removed CLS plateaus.
- Dashboard: Virtualized tables + chunked work improved INP.
- Blog: App Router static + ISR mixed—field LCP differed from lab → checked CDN cache keys and headers.
Troubleshooting
| Symptom | What to check |
|---|---|
| Lab good, field bad | Device, network, ads, browser extensions |
| LCP element keeps changing | Carousels/random heroes—stabilize the largest element’s load |
| Intermittent CLS | Fonts, delayed ads—reserve space and font strategy |
| INP only bad on one widget | Profile that script’s click path |
Conclusion
Web Vitals / LCP / CLS improvement is an iterative loop: measure → pick worst pages → remove LCP/CLS/INP bottlenecks in order. If you use Next.js App Router, align caching and server components with the App Router rendering guide to tackle TTFB and LCP together. Use field data as the baseline and improve incrementally.