블로그 목록

Core Web Vitals — LCP·INP·CLS의 의미와 개선법

2026-06-296 min read
성능Core Web VitalsLCPINPCLS

Core Web Vitals는 구글이 정한 실사용자 경험 지표다. 로딩(LCP)·반응성(INP)·시각 안정성(CLS) 세 축으로, 검색 순위에도 영향을 준다. 각 지표를 의미·기준·개선법으로 정리한다.

1. 세 지표 한눈에

Core Web Vitals — 실사용자 경험을 재는 3대 지표LCPLargest Contentful Paint로딩 속도최대 콘텐츠 표시 시간Good ≤ 2.5sPoor > 4.0sINPInteraction to Next Paint상호작용 반응성입력 → 다음 페인트Good ≤ 200msPoor > 500msCLSCumulative Layout Shift시각 안정성레이아웃 이동 누적Good ≤ 0.1Poor > 0.25

각 지표는 Good / 개선 필요 / Poor 구간으로 평가되며, 보통 75 퍼센타일(하위 사용자 75%) 기준으로 측정한다.

2. LCP — Largest Contentful Paint (로딩)

뷰포트에서 가장 큰 콘텐츠 요소(이미지·비디오·큰 텍스트 블록)가 그려지는 시점. "주요 콘텐츠가 떴다"고 느끼는 순간을 잰다.

  • 기준: Good ≤ 2.5초 / Poor > 4초

주요 원인

  1. 느린 서버 응답(TTFB)
  2. 렌더링 차단 리소스(CSS·JS)
  3. 느린 리소스 로딩(큰 이미지·폰트)
  4. 클라이언트 렌더링 지연

개선법

<!-- LCP 이미지에 우선순위 부여 -->
<link rel="preload" as="image" href="hero.webp" />
<img src="hero.webp" fetchpriority="high" />
  • 서버 응답 단축(CDN·캐시), 렌더 차단 리소스 줄이기(critical CSS, defer)
  • LCP 이미지 최적화: 포맷(WebP/AVIF), 적정 크기(srcset), preload·fetchpriority="high"
  • 폰트 최적화(font-display: swap, preload)

3. INP — Interaction to Next Paint (반응성)

사용자 상호작용(클릭·탭·키 입력)부터 그 결과가 화면에 그려질 때까지의 지연. 페이지 생애 동안 발생한 상호작용 중 가장 느린 축을 대표값으로 쓴다.

2024년 3월, 기존 FID(First Input Delay)를 공식 대체했다. FID는 "첫 입력의 지연"만 봤지만, INP는 모든 상호작용의 응답성을 보므로 더 엄격하다.

  • 기준: Good ≤ 200ms / Poor > 500ms

주요 원인: 무거운 JavaScript가 메인 스레드를 오래 점유 → 입력 처리가 밀림(long task)

개선법

  • 긴 작업을 쪼개기(time slicing), 불필요한 리렌더 줄이기
  • 급하지 않은 업데이트를 낮은 우선순위로 — React라면 useTransition·useDeferredValue (Concurrent 글)
  • 무거운 연산은 Web Worker로 메인 스레드에서 분리
  • 큰 리스트는 가상화(windowing)
// 무거운 목록 갱신을 낮은 우선순위로 → 입력 INP 보호
startTransition(() => setList(filterHugeList(query)));

4. CLS — Cumulative Layout Shift (시각 안정성)

예기치 않은 레이아웃 이동의 누적 점수. 로딩 중 콘텐츠가 갑자기 밀려 "버튼을 잘못 누르는" 경험을 수치화한다. 점수 = 이동 비율 × 영향 면적.

  • 기준: Good ≤ 0.1 / Poor > 0.25 (시간이 아니라 점수)

주요 원인

  1. 크기 미지정 이미지·광고·iframe → 로드되며 아래 콘텐츠를 밀어냄
  2. 늦게 주입되는 콘텐츠(배너·동적 위젯)
  3. 웹폰트 교체 시 글자 크기 변화(FOUT)

개선법

<!-- 크기를 미리 예약해 공간 확보 -->
<img src="thumb.webp" width="320" height="180" />
  • 이미지·비디오·광고 영역에 width/height 또는 aspect-ratio로 공간 예약
  • 동적 콘텐츠는 자리(placeholder)를 미리 확보
  • 폰트 교체 레이아웃 이동 최소화(size-adjust, 적절한 fallback)
  • 애니메이션은 레이아웃을 바꾸는 속성 대신 transform 사용 (렌더링 파이프라인 글)

5. 어떻게 측정하나 — Lab vs 필드

구분도구특징
Lab 데이터Lighthouse, DevTools통제된 환경에서 1회 측정. 디버깅용 (단 INP는 상호작용이 필요해 lab에서 부정확)
필드 데이터(RUM)CrUX, web-vitals 라이브러리실사용자의 실제 측정. 순위에 반영되는 진짜 값
import { onLCP, onINP, onCLS } from "web-vitals";
onLCP(console.log);
onINP(console.log);
onCLS(console.log); // 실제 사용자 값을 수집해 분석 도구로 전송

핵심: 개선은 lab으로 디버깅하되, 판단은 필드 데이터로 한다. 특히 INP는 실제 상호작용에서만 제대로 측정된다.

6. React / Next.js 관점

지표React/Next 도구
LCPnext/image(자동 최적화·priority), next/font(폰트 preload), SSR/RSC로 초기 콘텐츠 빠르게
INPuseTransition·useDeferredValue, 리렌더 최소화(불변성·구조적 공유), 코드 스플리팅
CLSnext/image의 width/height 자동 지정, 스켈레톤 placeholder

7. 정리

LCP(로딩, ≤2.5s)는 큰 콘텐츠를 빨리 — 서버·이미지·폰트 최적화. INP(반응성, ≤200ms)는 메인 스레드를 비워 — JS 쪼개기·useTransition. CLS(안정성, ≤0.1)는 레이아웃을 흔들지 않게 — 크기 예약·transform. 측정은 lab으로 디버깅, 필드 데이터로 판단한다.