frontend/javascript

🟨 2-29. Core Web Vitals 완전 해부 — LCP, CLS, FID로 웹 성능 측정하기

mirabo01 2025. 11. 7. 08:57

1. Core Web Vitals란?

Core Web Vitals는 Google이 웹페이지 품질을 평가하기 위한 3대 핵심 지표다.

지표 의미 목표 수치

LCP (Largest Contentful Paint) 페이지의 주요 콘텐츠가 언제 보이는가 2.5초 이하
FID (First Input Delay) 사용자가 처음 상호작용할 때 지연 시간 100ms 이하
CLS (Cumulative Layout Shift) 화면이 예기치 않게 흔들리는 정도 0.1 이하

📊 이 세 가지는 Google 검색 노출 순위에 직접적인 영향을 준다.


2. LCP (Largest Contentful Paint) — “언제 주요 콘텐츠가 보이나?”

✅ 정의

페이지의 가장 큰 콘텐츠(이미지, 텍스트 블록) 가 사용자 화면에 완전히 표시되는 데 걸리는 시간.

즉, “눈에 보이는 핵심 콘텐츠가 뜨는 순간”을 측정하는 지표다.

✅ 좋은 예

  • Hero 이미지가 빠르게 뜨는 페이지
  • 초기 렌더링에 필요한 자원만 미리 로드하는 구조

❌ 나쁜 예

  • 거대한 이미지, 광고, 폰트가 늦게 로딩
  • SSR(서버 사이드 렌더링) 없이 클라이언트 렌더링 지연

💡 개선 방법

전략 설명

이미지 최적화 WebP/AVIF 포맷, <img loading="lazy">
Critical CSS 인라인화 Above-the-fold 영역 CSS만 인라인 삽입
서버 응답 속도 개선 CDN 사용, SSR 적용
Preload 활용 <link rel="preload" as="image" href="hero.jpg">

3. FID (First Input Delay) — “첫 반응이 얼마나 빠른가?”

✅ 정의

사용자가 첫 클릭, 터치, 키 입력을 했을 때
브라우저가 이를 처리하기까지 걸린 지연 시간.

즉, “버튼을 눌렀는데 1초 뒤 반응하면 느리다고 느끼는 이유”를 수치화한 것이다.

✅ 좋은 예

  • 인터랙션이 즉시 반응하는 SPA
  • 메인 스레드가 차단되지 않은 상태

❌ 나쁜 예

  • JS 번들이 너무 커서 초기 실행이 느린 경우
  • 이벤트 리스너 등록이 늦게 일어나는 경우

💡 개선 방법

전략 설명

JS 번들 최소화 코드 스플리팅, Tree-shaking
비동기 로드 <script defer> 또는 async
Web Worker 활용 무거운 연산은 별도 스레드로 분리
우선순위 인터랙션 등록 DOMContentLoaded 시 즉시 이벤트 바인딩

4. CLS (Cumulative Layout Shift) — “화면이 갑자기 흔들리진 않는가?”

✅ 정의

페이지 내 요소들이 예기치 않게 이동하는 정도를 측정한다.
사용자가 버튼을 누르려는데 갑자기 광고가 밀려서 잘못 클릭하는 상황 — 그게 바로 높은 CLS다.

✅ 예시

❌ 나쁜 예

<img src="banner.jpg">
<p>본문 내용</p>

이미지 높이를 지정하지 않아, 이미지가 로드된 후 아래 콘텐츠가 밀림.

✅ 좋은 예

<img src="banner.jpg" width="800" height="400">

이미지 크기를 미리 지정 → 레이아웃 안정.

💡 개선 방법

전략 설명

width/height 지정 이미지, 영상, 광고 영역 크기 고정
폰트 교체 지연 방지 font-display: swap;
애니메이션 최적화 transform/opacity 기반만 사용
동적 콘텐츠 예약 공간 확보 로딩 중 placeholder로 자리 확보

5. 측정 방법

(1) Lighthouse (크롬 내장)

  • Chrome → 개발자 도구 → Lighthouse → Generate Report
  • LCP, CLS, FID를 한눈에 분석

✅ 각 항목별로 개선 가이드까지 자동 제공


(2) Chrome DevTools Performance 탭

  • Main Thread 활동 확인
  • Layout Shift 이벤트 시각화
  • 스크립트 실행 시간 분석

(3) Web Vitals JS 라이브러리

실제 사용자 데이터를 수집할 때 사용한다.

import { getCLS, getFID, getLCP } from 'web-vitals';

getCLS(console.log);
getFID(console.log);
getLCP(console.log);

✅ React, Next.js, Vue 등에서도 쉽게 통합 가능


6. 실제 예시 — 개선 전후 비교

지표 개선 전 개선 후

LCP 4.2초 1.9초
FID 280ms 85ms
CLS 0.25 0.05

✅ 개선 포인트

  • Hero 이미지 Preload
  • JS 번들 30% 감소
  • 폰트 Swap 적용
  • 광고 레이아웃 고정

7. SEO와의 관계

Core Web Vitals는
Google Page Experience Ranking에 직접 반영된다.

즉, 아무리 좋은 콘텐츠라도
LCP/FID/CLS가 낮으면 검색 노출 순위가 떨어진다.

✅ 구글은 “사용자 체감 성능”을 SERP(검색 결과) 순위의 요소로 사용 중이다.


8. 실무에서의 개선 전략

단계 수행 항목

1단계 (로딩 속도) 이미지 최적화, Preload, 압축
2단계 (JS 최적화) 코드 스플리팅, Lazy Load, Defer
3단계 (레이아웃 안정화) width/height 지정, transform 애니메이션
4단계 (모니터링) Web Vitals Script + Analytics 연동

9. 실제 Next.js 기준 개선 예시

// next.config.js
const withBundleAnalyzer = require('@next/bundle-analyzer')({
  enabled: process.env.ANALYZE === 'true',
});
module.exports = withBundleAnalyzer({
  images: {
    formats: ['image/avif', 'image/webp'],
  },
  compress: true,
});

✅ 자동 이미지 최적화
✅ JS 번들 압축 및 분석
✅ LCP/FID 향상


10. 마무리

Core Web Vitals는 단순한 기술 지표가 아니라
“사용자가 체감하는 웹 품질”을 수치화한 언어다.

LCP는 “언제 보이는가”
FID는 “언제 반응하는가”
CLS는 “얼마나 안정적인가”

이 세 가지를 개선하면
단순히 빠른 페이지가 아니라 신뢰받는 사용자 경험을 제공할 수 있다.