SOYOYU
블로그로 돌아가기기술 SEO

Core Web Vitals 2026 감사 체크리스트: INP 시대의 성능 점검법

2026년 Core Web Vitals 감사를 단계별로 안내합니다. LCP, INP, CLS 임계값부터 도구 선택, 디버깅 워크플로, 자동화 모니터링까지 실무 체크리스트를 제공합니다.

소요유2026년 5월 14일12 min read
Core Web VitalsINPLCPCLS기술 SEO성능 최적화

TL;DR: 2026년 CWV 감사, 이것만 기억하세요

  • 3대 지표: LCP 2.5초, INP 200ms, CLS 0.1 이하 — 모두 75번째 백분위수 기준
  • 현실: 전체 사이트 중 47%만 세 가지 기준을 동시에 충족
  • 도구 구분: 필드 데이터(실제 사용자)와 랩 데이터(시뮬레이션)를 혼동하면 진단이 틀어짐
  • 핵심 변화: Lighthouse는 INP를 측정할 수 없음 — TBT를 프록시로 사용할 뿐
  • 네이버: CWV를 랭킹 시그널로 사용하지 않음 — 다만 UX와 AI 크롤러 접근성에는 영향

이 가이드의 구조

CWV 감사를 5단계 워크플로로 진행합니다. 순서대로 따라가면 현재 상태 파악부터 지속적 모니터링까지 한 번에 끝낼 수 있습니다.

  1. 현황 파악 — Search Console과 CrUX로 필드 데이터 확인
  2. 도구 선택 — 목적에 맞는 도구를 정확히 고르기
  3. LCP 감사 — 4가지 하위 구간을 개별 점검
  4. INP 감사 — 필드에서 문제 식별, 랩에서 원인 추적
  5. CLS 감사 — 랩 도구가 놓치는 포스트 로드 CLS 잡아내기
  6. 자동화 — 사전/사후 모니터링 파이프라인 구축

1단계: 현황 파악 — 현재 CWV 상태 확인

Google Search Console CWV 리포트

Search Console(검색 콘솔)의 Core Web Vitals 리포트는 감사의 출발점입니다. 모바일과 데스크톱을 분리하여 LCP, INP, CLS 상태를 보여줍니다.

2026년 기준 Search Console 리포트 현황을 정리합니다.

리포트상태비고
Core Web Vitals활성LCP, INP, CLS — 모바일/데스크톱 분리
Page Experience폐지CWV 리포트가 남은 유일한 구성요소
모바일 사용성폐지2023년 12월 종료
FID 열제거INP로 완전 대체

출처: Google Search Central — Core Web Vitals report

CWV 임계값 기준표

세 지표 모두 75번째 백분위수(p75) 기준으로 평가됩니다. 상위 25%가 아니라 하위 75%의 경험이 기준을 충족해야 합니다.

지표좋음개선 필요나쁨측정 대상
LCP≤ 2.5초≤ 4초> 4초가장 큰 콘텐츠 요소의 렌더 시간
INP≤ 200ms≤ 500ms> 500ms전체 세션에서 가장 느린 상호작용 응답
CLS≤ 0.1≤ 0.25> 0.25페이지 전체 수명 동안의 레이아웃 이동 누적

감사 체크리스트: 현황 파악

  • Search Console에서 CWV 리포트 확인 (모바일/데스크톱 별도 점검)
  • "불량" URL 그룹 목록 확인 및 우선순위 정리
  • CrUX 데이터 유무 확인 — 트래픽이 적으면 필드 데이터가 없을 수 있음
  • 폐지된 Page Experience, 모바일 사용성 리포트에 의존하고 있지 않은지 확인

2단계: 도구 선택 — 필드 vs 랩의 차이를 이해하기

CWV 감사에서 가장 흔한 실수는 필드 데이터(Field Data)와 랩 데이터(Lab Data)를 구분하지 않는 것입니다.

  • 필드 데이터: 실제 사용자의 브라우저에서 수집된 데이터. CrUX(Chrome User Experience Report)가 대표적
  • 랩 데이터: 통제된 환경에서 시뮬레이션한 데이터. Lighthouse가 대표적

구글이 순위 결정에 사용하는 것은 필드 데이터입니다.

도구별 역할과 한계

도구데이터 유형INP 측정CLS 범위주 용도
PageSpeed Insights필드(CrUX) + 랩(Lighthouse)필드만 가능필드: 전체 수명 / 랩: 로드 시점만빠른 감사, 필드-랩 비교
Lighthouse v10랩 전용불가 (TBT를 프록시로 사용)로드 시점만CI 통합, 사전 배포 점검
Chrome DevToolsLive Metrics에서 실시간 모니터링세션 중실시간 디버깅, INP 원인 추적
web-vitals.js v5필드(RUM)가능 + Attribution 빌드로 원인 분석전체 수명자체 RUM 수집, 프로덕션 모니터링
CrUX API / BigQuery필드가능전체 수명경쟁사 분석, 대규모 데이터 분석

출처: web.dev — Lighthouse performance scoring

Lighthouse v10 성능 가중치 참고:

지표가중치
TBT (Total Blocking Time)30%
LCP25%
CLS25%
FCP (First Contentful Paint)10%
Speed Index10%

TBT는 INP의 프록시일 뿐이며, 실제 사용자의 상호작용 패턴을 반영하지 못합니다. Lighthouse 점수가 높아도 필드 INP가 나쁠 수 있습니다.

감사 체크리스트: 도구 선택

  • PageSpeed Insights에서 필드 데이터(CrUX) 확인 — "필드 데이터" 섹션이 표시되는지 점검
  • Lighthouse 점수만으로 INP를 판단하고 있지 않은지 확인
  • CLS 감사에 랩 도구만 사용하고 있지 않은지 확인 (포스트 로드 CLS를 놓침)
  • 자체 RUM 수집이 필요한지 결정 (web-vitals.js 도입 여부)

3단계: LCP 감사 — 4가지 하위 구간 분석

LCP는 단일 지표이지만 내부적으로 4가지 하위 구간으로 나뉩니다. Chrome 팀의 분석에 따르면 각 구간이 LCP에 기여하는 비율이 다르며, 최적화 우선순위도 달라집니다.

출처: web.dev — Optimize LCP

LCP 하위 구간 분석표

하위 구간설명권장 비율실제 문제 빈도
TTFB (Time to First Byte)서버 응답까지의 시간~40%높음 — CDN 미사용이 주 원인
리소스 로드 지연 (Resource Load Delay)LCP 리소스 발견~다운로드 시작< 10%매우 높음 — p75 중앙값 1,290ms
리소스 로드 시간 (Resource Load Duration)LCP 리소스 다운로드 시간~40%중간 — 이미지 최적화로 개선
요소 렌더 지연 (Element Render Delay)다운로드 완료~화면 렌더링< 10%낮음 — 렌더 차단 리소스가 원인

핵심 통계: LCP가 나쁜 사이트 중 리소스 로드 지연의 p75 중앙값이 1,290ms에 달합니다. 이미지 자체가 무거운 게 아니라, 브라우저가 이미지를 발견하는 데 걸리는 시간이 문제입니다.

LCP 최적화 체크리스트

TTFB 최적화

  • HTML 문서에 CDN 적용 여부 확인 — 전체 HTML 요청 중 33%만 CDN을 거침
  • 서버 응답 시간 600ms 이하 유지 (이상적으로 200ms 이하)
  • 리다이렉트 체인 제거 — 각 리다이렉트가 TTFB에 누적
  • 서버 사이드 캐싱(Redis, CDN edge cache) 적용 여부

리소스 로드 지연 최적화

  • LCP 이미지에 fetchpriority="high" 적용 — 현재 15%의 페이지만 사용
  • LCP 이미지에 loading="lazy" 적용하지 않았는지 확인 — 절대로 LCP 이미지를 지연 로드하면 안 됨
  • LCP 이미지가 HTML에 직접 포함되어 있는지 확인 (CSS background-image가 아닌 <img> 태그)
  • <link rel="preload"> 또는 <link rel="preconnect">로 LCP 리소스 힌트 제공
<!-- LCP 이미지 최적화 예시 -->
<link rel="preconnect" href="https://cdn.example.com">

<!-- LCP 이미지: fetchpriority="high", loading="lazy" 절대 금지 -->
<img
  src="/hero-image.webp"
  alt="서비스 소개 이미지"
  width="1200"
  height="630"
  fetchpriority="high"
/>

리소스 로드 시간 최적화

  • LCP 이미지를 WebP 또는 AVIF 포맷으로 변환
  • <img> 태그에 width, height 속성 명시 (CLS 방지 겸용)
  • 적절한 srcsetsizes로 뷰포트별 이미지 제공
  • 이미지 CDN(Cloudinary, imgix 등) 사용 여부

요소 렌더 지연 최적화

  • 렌더 차단 CSS 최소화 — critical CSS 인라인 삽입
  • 렌더 차단 JavaScript에 defer 또는 async 적용
  • LCP 요소가 클라이언트 사이드 렌더링에 의존하지 않는지 확인 (SSR/SSG 권장)

4단계: INP 감사 — 필드에서 찾고, 랩에서 진단하기

INP는 CWV 3대 지표 중 가장 디버깅이 어렵습니다. FID가 "첫 번째 상호작용의 입력 지연"만 측정한 반면, INP는 전체 세션의 모든 상호작용 중 가장 느린 것을 보고합니다.

실험실 환경에서는 실제 사용자의 클릭, 스크롤, 키 입력 패턴을 재현할 수 없기 때문에 필드 데이터가 필수입니다.

INP 디버깅 4단계 워크플로

Phase 1: 필드에서 문제 식별

CrUX와 web-vitals.js의 Attribution 빌드로 어떤 상호작용이 문제인지 파악합니다.

// web-vitals.js v5 — INP Attribution 수집 예시
import { onINP } from 'web-vitals/attribution';

onINP((metric) => {
  const { name, value, attribution } = metric;
  const {
    interactionTarget,      // 상호작용 대상 요소
    interactionType,        // 'pointer', 'keyboard' 등
    inputDelay,             // 입력 지연 (ms)
    processingDuration,     // 처리 시간 (ms)
    presentationDelay,      // 표시 지연 (ms)
    longAnimationFrameEntries // 관련 LoAF 항목
  } = attribution;

  // 분석 도구로 전송
  sendToAnalytics({
    metric: name,
    value: Math.round(value),
    target: interactionTarget,
    type: interactionType,
    inputDelay: Math.round(inputDelay),
    processingDuration: Math.round(processingDuration),
    presentationDelay: Math.round(presentationDelay),
  });
});

참고: web-vitals.js v5의 Attribution 빌드는 약 3.5KB이며, 일반 빌드보다 크지만 원인 분석에 필수적인 데이터를 제공합니다.

Phase 2: 랩에서 재현

Chrome DevTools(개발자 도구)의 Performance 패널과 Live Metrics 뷰에서 문제 상호작용을 재현합니다.

  • DevTools Performance 패널에서 해당 상호작용을 녹화
  • Live Metrics 뷰에서 실시간 INP 값 확인
  • CPU 4x/6x 쓰로틀링을 켜서 저사양 기기 환경 시뮬레이션

Phase 3: 3가지 구간으로 원인 진단

INP는 세 구간의 합산입니다. 어느 구간이 병목인지에 따라 대응이 달라집니다.

구간설명주요 원인
Input Delay클릭/키 입력 후 이벤트 핸들러 시작까지메인 스레드를 점유 중인 다른 태스크
Processing Duration이벤트 핸들러 실행 시간복잡한 로직, 동기 API 호출, 레이아웃 강제
Presentation Delay핸들러 완료 후 다음 프레임 렌더링까지과도한 DOM 변경, 스타일 재계산

Phase 4: 수정 적용

  • Input Delay가 긴 경우: scheduler.yield()로 장기 태스크를 분할하여 메인 스레드 양보
  • Processing Duration이 긴 경우: 이벤트 핸들러 내 로직 최소화, 불필요한 동기 작업 제거
  • Presentation Delay가 긴 경우: DOM 변경 최소화, requestAnimationFrame() 활용
  • 레이아웃 스래싱(layout thrashing) 방지 — 읽기/쓰기를 분리
  • 불필요한 서드파티 스크립트 제거 또는 지연 로드
  • 전체 JavaScript 번들 크기 점검 및 코드 분할 적용
// scheduler.yield()로 장기 태스크 분할 예시
async function handleComplexClick() {
  // 1단계: 즉각적인 UI 피드백
  updateButtonState();

  // 메인 스레드를 양보하여 브라우저가 렌더링할 수 있게 함
  await scheduler.yield();

  // 2단계: 무거운 연산
  processData();

  await scheduler.yield();

  // 3단계: 결과 반영
  updateResults();
}

INP 감사 체크리스트

  • CrUX 또는 web-vitals.js에서 INP p75 값 확인
  • INP가 200ms를 초과하는 페이지 목록 작성
  • Attribution 데이터로 문제 상호작용(대상 요소, 유형) 식별
  • 3가지 구간(Input Delay / Processing / Presentation) 중 병목 파악
  • Lighthouse TBT 점수만으로 INP를 판단하고 있지 않은지 확인
  • scheduler.yield() 또는 태스크 분할 적용

5단계: CLS 감사 — 랩 도구가 놓치는 것들

CLS는 세 지표 중 랩과 필드의 괴리가 가장 큰 지표입니다. Lighthouse는 페이지 로드 시점의 CLS만 측정하지만, CrUX는 페이지 전체 수명 동안의 CLS를 측정합니다.

실제로 CLS 문제의 상당수는 로드 이후에 발생합니다 — 스크롤 중 광고 삽입, 쿠키 배너 표시, 무한 스크롤 콘텐츠 로딩 등.

CLS에서 자주 놓치는 문제들

문제 유형설명도구 감지 여부
포스트 로드 CLS로드 이후 발생하는 레이아웃 이동Lighthouse 불가 / CrUX 감지
애니메이션 유발 CLSmargin, border 등 레이아웃 속성 애니메이션CrUX 감지 — 해당 페이지는 "나쁨" 비율이 2배
iframe CLS광고 iframe 등에서 발생하는 레이아웃 이동CrUX 포함 / web-vitals.js 측정 불가
bfcache 미적격뒤로/앞으로 캐시 불가로 페이지 재로드 발생간접적으로 CLS 증가

출처: web.dev — Optimize CLS

CLS 최적화 체크리스트

기본 점검

  • 모든 이미지와 비디오에 width, height 속성 또는 CSS aspect-ratio 지정
  • 광고 슬롯에 고정 크기 컨테이너(min-height) 사전 확보
  • 웹폰트 로드 시 font-display: swapsize-adjust로 FOUT 최소화
  • 동적으로 삽입되는 콘텐츠(배너, 알림)에 공간 사전 확보

애니메이션 점검

  • margin, padding, border, top, left 등 레이아웃 속성을 애니메이션하고 있지 않은지 확인
  • 레이아웃 애니메이션을 transformopacity로 대체
  • CSS will-change 속성을 꼭 필요한 요소에만 적용
/* 나쁜 예: 레이아웃 속성 애니메이션 — CLS "나쁨" 비율 2배 */
.slide-in {
  animation: slideIn 0.3s ease;
}
@keyframes slideIn {
  from { margin-left: -100%; }
  to { margin-left: 0; }
}

/* 좋은 예: transform 사용 — CLS에 영향 없음 */
.slide-in {
  animation: slideIn 0.3s ease;
}
@keyframes slideIn {
  from { transform: translateX(-100%); }
  to { transform: translateX(0); }
}

bfcache 점검

bfcache(Back/Forward Cache)가 작동하지 않으면 뒤로/앞으로 버튼 클릭 시 페이지를 처음부터 다시 로드하여 CLS가 재발합니다.

  • Cache-Control: no-store 헤더를 불필요하게 사용하고 있지 않은지 확인
  • unload 이벤트 리스너 제거 — pagehide 또는 visibilitychange로 대체
  • DevTools의 Application > Back/forward cache에서 적격 여부 테스트

iframe 점검

  • 광고 iframe에 고정 크기 컨테이너 지정
  • web-vitals.js로는 iframe 내부 CLS를 측정할 수 없다는 점 인식 — CrUX 데이터와 비교 필요

6단계: 자동화 모니터링 — 사전 + 사후 파이프라인

CWV 감사는 일회성이 아닙니다. 코드 배포 하나로 성능이 급락할 수 있으므로 사전 배포(Pre-deploy)와 사후 배포(Post-deploy) 모니터링을 모두 갖춰야 합니다.

왜 둘 다 필요한가?

단계도구역할한계
사전 배포Lighthouse CI릴리스 전에 성능 회귀 감지랩 데이터만 — 실제 사용자 패턴 반영 못 함
사후 배포web-vitals.js (RUM)실제 사용자 경험 측정데이터 수집까지 시간 필요 (최소 수시간~수일)

Lighthouse CI 설정 예시

// lighthouserc.js
module.exports = {
  ci: {
    collect: {
      url: [
        'https://example.com/',
        'https://example.com/blog/',
        'https://example.com/contact/',
      ],
      numberOfRuns: 3,
    },
    assert: {
      assertions: {
        'largest-contentful-paint': ['error', { maxNumericValue: 2500 }],
        'total-blocking-time': ['error', { maxNumericValue: 300 }],
        'cumulative-layout-shift': ['error', { maxNumericValue: 0.1 }],
        'first-contentful-paint': ['warn', { maxNumericValue: 1800 }],
      },
    },
    upload: {
      target: 'temporary-public-storage',
    },
  },
};

참고: Lighthouse CI의 total-blocking-time은 INP의 프록시입니다. 필드 INP와 정확히 대응하지 않으므로 사후 모니터링과 반드시 병행해야 합니다.

web-vitals.js RUM 수집 예시

// web-vitals.js v5 — 전체 CWV 수집
import { onLCP, onINP, onCLS } from 'web-vitals/attribution';

function sendToAnalytics(metric) {
  const body = JSON.stringify({
    name: metric.name,
    value: Math.round(metric.name === 'CLS' ? metric.value * 1000 : metric.value),
    rating: metric.rating,  // 'good', 'needs-improvement', 'poor'
    url: location.href,
    // Attribution 데이터 (원인 분석용)
    ...(metric.attribution && {
      attribution: metric.attribution,
    }),
  });

  // sendBeacon으로 페이지 이탈 시에도 데이터 유실 방지
  if (navigator.sendBeacon) {
    navigator.sendBeacon('/api/vitals', body);
  } else {
    fetch('/api/vitals', { body, method: 'POST', keepalive: true });
  }
}

onLCP(sendToAnalytics);
onINP(sendToAnalytics);
onCLS(sendToAnalytics);

모니터링 자동화 체크리스트

  • CI/CD 파이프라인에 Lighthouse CI 통합 — 빌드마다 자동 실행
  • 성능 예산(Performance Budget) 설정 — 임계값 초과 시 빌드 실패 처리
  • web-vitals.js를 프로덕션에 배포하여 RUM 데이터 수집
  • RUM 데이터를 대시보드(GA4, 자체 대시보드)에서 주 단위 모니터링
  • 필드 데이터와 랩 데이터 간 괴리가 있을 때 원인 분석 프로세스 수립

네이버와 CWV: 한국 시장 특수성

한국 시장에서 일하는 분들이 자주 묻는 질문입니다.

네이버는 CWV를 랭킹 시그널로 사용하지 않습니다. 네이버 검색 가이드에 CWV 관련 언급이 없으며, 별도의 페이지 경험 평가 체계도 공개하지 않았습니다.

그렇다면 CWV를 무시해도 될까요? 그렇지 않습니다.

  • 사용자 경험: 느린 사이트는 검색엔진과 무관하게 이탈률이 높아집니다
  • Google 트래픽: 한국에서도 Google 검색 비중이 지속적으로 증가하고 있습니다
  • AI 크롤러 접근성: ChatGPT, Perplexity 등 AI 크롤러는 1~5초 타임아웃으로 작동합니다. TTFB가 느리면 크롤링 자체가 실패합니다

CWV와 AI 검색의 관계에 대해 더 자세히 알고 싶다면 Core Web Vitals와 AI 검색의 상관관계 글을 참고하세요.


종합 감사 체크리스트

전체 워크플로를 한 장으로 정리합니다. 분기별 정기 감사 시 이 표를 기준으로 점검하세요.

현황 및 도구 (매 감사 시작 시)

항목점검
Search Console CWV 리포트 확인[ ]
PageSpeed Insights에서 필드 데이터 확인[ ]
폐지된 리포트(Page Experience, 모바일 사용성) 의존 여부[ ]
필드/랩 데이터 구분 이해[ ]

LCP (목표: ≤ 2.5초)

항목점검
HTML 문서에 CDN 적용[ ]
LCP 이미지에 fetchpriority="high"[ ]
LCP 이미지에 loading="lazy" 미적용 확인[ ]
LCP 이미지가 HTML <img> 태그로 제공[ ]
이미지 WebP/AVIF 포맷 적용[ ]
렌더 차단 리소스 제거 또는 지연[ ]
TTFB 600ms 이하 유지[ ]

INP (목표: ≤ 200ms)

항목점검
CrUX 또는 RUM에서 INP p75 확인[ ]
Attribution 데이터로 문제 상호작용 식별[ ]
3구간 중 병목(Input Delay / Processing / Presentation) 파악[ ]
장기 태스크 분할 (scheduler.yield())[ ]
불필요한 서드파티 스크립트 제거[ ]
Lighthouse TBT에만 의존하지 않는지 확인[ ]

CLS (목표: ≤ 0.1)

항목점검
이미지/비디오 width, height 명시[ ]
광고 슬롯 고정 크기 확보[ ]
레이아웃 속성 애니메이션 → transform 대체[ ]
bfcache 적격 여부 확인[ ]
포스트 로드 CLS 확인 (필드 데이터 필수)[ ]
iframe CLS 확인 (CrUX와 비교)[ ]

자동화

항목점검
Lighthouse CI 파이프라인 구축[ ]
web-vitals.js RUM 프로덕션 배포[ ]
성능 예산 설정 및 알림[ ]
주간/월간 필드 데이터 리뷰 프로세스[ ]

FAQ

Q. Lighthouse 점수가 90점 이상인데 Search Console에서 "나쁨"이 뜹니다. 왜 그런가요?

Lighthouse는 랩 데이터이고, Search Console은 필드 데이터(CrUX)입니다. 랩에서는 통제된 환경(고정 네트워크, 고정 기기)으로 테스트하지만, 필드에서는 실제 사용자의 다양한 기기와 네트워크 환경이 반영됩니다. 특히 INP와 포스트 로드 CLS는 Lighthouse가 제대로 측정하지 못합니다.

Q. INP를 Lighthouse로 테스트할 수 없다면 어떻게 개선하나요?

1단계로 CrUX 또는 web-vitals.js의 Attribution 빌드에서 문제 상호작용을 식별하고, 2단계로 Chrome DevTools Performance 패널에서 해당 상호작용을 재현하여 3가지 구간(Input Delay, Processing, Presentation)의 병목을 찾습니다.

Q. CWV가 나쁘면 Google 순위가 떨어지나요?

CWV는 Google의 랭킹 시그널 중 하나이지만, 콘텐츠 관련성이 여전히 가장 중요합니다. CWV는 콘텐츠 품질이 비슷한 경쟁 페이지들 사이에서 차별화 요소로 작용합니다. 세 지표를 모두 "좋음"으로 달성하면 경쟁 쿼리에서 유리한 위치를 점할 수 있습니다.

Q. 트래픽이 적어서 CrUX에 데이터가 없습니다. 어떻게 해야 하나요?

CrUX 데이터가 없으면 Google은 해당 페이지에 대해 CWV를 순위 요소로 적용하지 않습니다. 그러나 사용자 경험을 위해 최적화는 여전히 권장됩니다. web-vitals.js를 직접 배포하여 자체 RUM 데이터를 수집하면 트래픽이 적어도 성능을 모니터링할 수 있습니다.

Q. scheduler.yield()는 모든 브라우저에서 사용할 수 있나요?

2026년 현재 Chromium 기반 브라우저(Chrome, Edge)에서 지원됩니다. 비지원 브라우저에서는 폴백으로 setTimeout(resolve, 0)을 사용할 수 있지만, 우선순위 유지가 되지 않는다는 차이가 있습니다. 프로그레시브 인핸스먼트 방식으로 적용하세요.


관련 글


Core Web Vitals 감사가 필요하시면 XEO 무료 진단을 신청하세요.

검색 최적화가 필요하신가요?

무료 상담을 통해 비즈니스에 맞는 최적화 전략을 확인하세요.