궁극의 Core Web Vitals 체크리스트 (2026)

LCP, INP, CLS 성능 개선 시 확인해야 할 모든 최적화 항목

Arjen Karel Core Web Vitals Consultant
Arjen Karel - linkedin
Last update: 2026-06-18

완벽한 Core Web Vitals 체크리스트

이 Core Web Vitals 체크리스트는 새 사이트를 배포하기 전, Largest Contentful Paint(LCP), Interaction to Next Paint(INP), Cumulative Layout Shift(CLS)를 개선할 때, 혹은 사이트에 큰 변화를 줄 때 확인해야 할 모든 최적화 항목을 다룹니다. 웹사이트가 빠르고 매끄러운 경험을 제공하여 Google의 Core Web Vitals 평가를 통과하도록 실용적인 참고 자료로 사용하십시오.

이 체크리스트는 최신 정보에 따라 지속적으로 업데이트됩니다. 기여하고 싶다면 언제든 연락해 주십시오.

core web vitals lcp inp cls

Core Web Vitals 최적화 체크리스트

완벽한 Core Web Vitals 체크리스트입니다. 이를 사용해 성능 문제를 파악하고 모든 방문자에게 빠르고 매끄러운 웹사이트를 제공하십시오. 각 체크리스트 섹션은 관련 세부 가이드로 연결되므로 모든 권장 사항의 "이유"를 학습할 수 있습니다.

이미지 최적화

표시되는 viewport의 큰 이미지는 대부분 Largest Contentful Paint 요소가 됩니다. 이미지 최적화는 LCP에 가장 큰 영향을 미치는 작업 중 하나입니다. 이 Core Web Vitals 체크리스트 항목을 사용하여 이미지 속도를 개선하십시오. 전체 전략은 LCP 이미지 최적화 방법 가이드를 읽어보십시오.

  • 화면의 가장 큰 크기에 맞춰 이미지 크기 조정: 화면 최대 크기보다 큰 이미지를 다운로드하여 바이트를 낭비하지 않도록 합니다. 작은 화면 크기에는 반응형 이미지를 함께 사용하십시오. 올바른 크기의 이미지를 제공하면 눈에 띄는 품질 저하 없이 이미지 파일 크기를 50% 이상 줄일 수 있습니다.
  • 스크롤을 해야 보이는 이미지에 lazy loading 사용: lazy loading은 viewport 밖의 이미지가 스크롤되어 보일 때까지 로딩을 지연시켜 First Contentful Paint (FCP)와 전반적인 페이지 로드 속도를 개선합니다. LCP 이미지에 lazy loading을 적용하면 엄청난 지연을 초래하므로 절대 사용하지 마십시오.
  • LCP 요소 등 시각적으로 중요한 이미지 사전 로드: 사전 로드는 브라우저가 다른 콘텐츠보다 먼저 중요 이미지를 가져오도록 지시하여 LCP에 우선순위를 부여합니다. 최상의 결과를 얻으려면 fetchpriority="high"와 함께 <link rel="preload" as="image">를 사용하십시오. 이는 CSS에서 LCP 이미지를 참조하거나 JavaScript를 통해 로드할 때 특히 중요합니다.
  • 너비 및 높이 설정: 이미지 크기를 미리 정의하면 브라우저가 이미지 로딩을 기다리며 발생하는 layout shift를 방지합니다. 이는 CLS를 개선합니다. 최신 브라우저는 이미지가 로드되기 전에 너비 및 높이 속성을 사용하여 가로세로 비율을 계산하고 적절한 공간을 예약합니다.
  • WebP 또는 AVIF와 같은 최신 이미지 형식 사용: 이러한 형식은 JPEG 또는 PNG에 비해 비슷한 품질을 유지하면서 더 작은 파일 크기를 제공하여 로드 시간을 단축시킵니다. WebP는 일반적으로 JPEG보다 25-34% 작은 파일 크기를 달성하며, AVIF는 파일 크기를 최대 50%까지 줄일 수 있습니다. 최대 브라우저 호환성을 위해 형식 fallback이 있는 <picture> 요소를 사용하십시오.
  • 네이티브 lazy loading 사용 및 JavaScript 기반 lazy loading 비활성화: lazy loading은 viewport 밖의 이미지가 스크롤되어 보일 때까지 로딩을 지연시킵니다. 브라우저가 loading="lazy" 속성을 통해 제공하는 네이티브 lazy loading은 JavaScript에 의존하는 것보다 일반적으로 더 효율적입니다. 추가적인 스크립트 파싱이나 실행이 필요하지 않기 때문입니다.
  • srcset으로 반응형 이미지 사용: 이 속성은 다양한 화면 크기에 대해 각기 다른 이미지 버전을 지정하여 브라우저가 사용자의 기기에 최적의 이미지를 제공하도록 보장하고, 불필요한 대용량 다운로드를 줄입니다. 정밀한 제어를 위해 srcsetsizes 속성과 결합하십시오.
  • decoding="async" 추가: decoding="async" 속성은 브라우저가 이미지를 디코딩하는 동안 다른 콘텐츠를 차단하는 것을 방지합니다. 이를 통해 이미지 디코딩이 병렬로 진행되는 동안 렌더링 엔진이 다른 요소의 페인팅을 계속할 수 있습니다.
  • 이미지 메타데이터 제거: 이미지에 포함된 EXIF 데이터와 같은 메타데이터는 불필요한 바이트를 추가할 수 있습니다. 이 정보를 제거하면 이미지 품질에 영향을 주지 않고 파일 크기를 줄일 수 있습니다. ImageOptim, Squoosh, Sharp와 같은 도구를 사용하면 빌드 프로세스의 일부로 메타데이터 제거를 자동화할 수 있습니다.
  • LCP 요소에 CSS 배경 이미지 사용 피하기: CSS에서 참조된 배경 이미지는 HTML의 <img> 요소보다 브라우저에서 늦게 발견됩니다. 배경 이미지를 LCP 요소로 사용해야 한다면 <link rel="preload"> 태그로 사전 로드하여 조기 발견을 보장하십시오. LCP 리소스 로드 지연에 대해 자세히 알아보십시오.

웹 폰트 최적화

웹 폰트는 First Contentful Paint를 지연시키고 layout shift를 유발하며 초기 대역폭 리소스를 두고 경쟁할 수 있습니다. 매끄러운 웹 폰트 경험을 보장하려면 이 체크리스트를 사용하십시오. 폰트 호스팅 모범 사례는 Google Fonts 자체 호스팅 가이드를 참조하십시오.

  • 더 빠른 첫 페인트를 위해 font-display: swap 사용: @font-face 선언에서 font-display 속성을 swap으로 설정하십시오. 이는 백그라운드에서 웹 폰트를 로드하는 동안 브라우저가 즉시 fallback 폰트를 표시하도록 보장합니다. 폰트가 준비되면 자연스럽게 교체합니다. 웹 폰트 로드 중 텍스트가 표시되도록 보장하는 방법을 자세히 읽어보십시오.
  • 폰트로 인한 layout shift를 없애기 위해 font-display: optional과 사전 로드 결합: font-display: optional과 사전 로드를 결합하면 속도와 잠재적인 layout shift 사이의 균형을 제공합니다. optional 값은 fallback 폰트를 사용하기 전에 텍스트를 잠깐(약 100ms) 숨깁니다. 사전 로드는 브라우저가 웹 폰트를 일찍 가져오도록 지시하여 fallback 폰트에 소요되는 시간을 최소화하고 layout shift를 줄입니다.
  • fallback 폰트가 웹 폰트의 크기와 일치하도록 font-face 디스크립터 사용: 이는 웹 폰트가 교체될 때 CLS를 최소화합니다. fallback 폰트에 size-adjust, ascent-override, descent-override, line-gap-override를 사용하여 유사한 메트릭을 지정하면 폰트가 로드될 때 콘텐츠가 튀는 것을 방지할 수 있습니다.
  • 필요한 문자만 포함하도록 폰트 서브셋(subset) 생성: 콘텐츠에 필요한 문자만 포함하도록 폰트를 서브셋으로 만들어 폰트 파일 크기를 줄이십시오. Font Squirrel, pyftsubset, glyphhanger와 같은 도구를 사용하면 서브셋을 생성할 수 있습니다. 적절한 서브셋을 적용하면 전체 라틴 문자 세트 폰트를 종종 100KB 이상에서 20KB 미만으로 줄일 수 있습니다.
  • 폰트 굵기 및 스타일 수 제한: 과도한 폰트 변형을 로드하지 마십시오. 최대 2개의 중요 폰트(보통 사전 로드됨)와 2개의 지연 로드 폰트(초기 렌더링 후 로드됨)로 유지하십시오. 폰트 굵기가 추가될 때마다 다운로드 크기가 15~50KB 증가합니다.

스크립트 최적화

스크립트는 Interaction to Next Paint 문제를 유발하거나 Cumulative Layout Shift를 촉발하거나 Largest Contentful Paint를 지연시킬 수 있습니다. 최적화되고 비교적 무해한 초기 스크립트라 하더라도 리소스 경쟁을 통해 페인트 메트릭(LCP 및 FCP)을 지연시킬 수 있습니다. 전체 가이드는 JavaScript를 지연시키는 14가지 방법을 참조하십시오.

  • 불필요한 JavaScript 제거: 사용되지 않는 JavaScript 코드를 식별하고 제거하여 다운로드 및 실행해야 하는 코드 양을 최소화하십시오. Chrome DevTools의 Coverage 탭을 사용하여 사용하지 않는 코드를 찾으십시오. 죽은 코드를 제거하면 다운로드 시간과 main thread 처리량이 모두 줄어듭니다.
  • 기능과 중요도에 따라 스크립트 우선순위 지정: 표시되는 viewport에 큰 변경을 주는 스크립트는 render blocking이어야 합니다. 중요한 스크립트는 지연시키거나 비동기로 로드해야 합니다. 있으면 좋은 부가적인 스크립트는 브라우저가 idle 상태일 때 로드해야 합니다. 자세한 전략은 리소스 우선순위 지정 가이드를 참조하십시오.
  • 코드 스플리팅 및 lazy loading: 대규모 JavaScript 번들을 작은 청크로 나누고 필요할 때만 로드하십시오. 이는 초기 로드 시간을 줄여줍니다. webpack, Rollup, esbuild와 같은 최신 번들러는 동적 import를 기반으로 자동 코드 스플리팅을 지원합니다.
  • JavaScript 파일 최소화 및 재컴파일: SWC, Terser, esbuild와 같은 최소화 도구를 사용하여 항상 JavaScript 파일을 최소화하고 재컴파일하십시오. 최소화는 일반적으로 JavaScript 파일 크기를 30~50% 줄여줍니다.
  • 서드파티 스크립트 제한: 서드파티 스크립트는 상당한 성능 오버헤드를 유발할 수 있습니다. 필요성을 평가하고 가능하면 대안을 모색하십시오. 각 서드파티 스크립트는 DNS 조회, 연결 오버헤드, main thread 처리 시간을 추가합니다. Chrome DevTools의 Network 패널을 사용하여 정기적으로 서드파티 스크립트를 감사하십시오.
  • 서드파티 스크립트 비동기 로드: 서드파티 스크립트의 예측할 수 없는 특성 때문에 렌더링이 서드파티에 의해 차단되도록 두지 마십시오. 모든 서드파티 스크립트 태그에 async 또는 defer 속성을 사용하십시오.
  • 서드파티 스크립트 성능 모니터링: Long Animation Frames (LoAF) API 또는 CoreDash를 사용하여 서드파티 스크립트가 INPLCP에 미치는 실제 영향을 추적하십시오. 서드파티 JavaScript에 대한 성능 예산을 설정하고 정기적으로 검토하십시오.

스타일 최적화

스타일은 기본적으로 render blocking입니다. 스타일을 최적화하면 페인트 메트릭도 최적화됩니다. 웹페이지의 스타일 성능을 향상하려면 이 체크리스트를 따르십시오. render blocking CSS는 First Contentful PaintLCP 요소 렌더링 지연 모두에 직접적인 영향을 미칩니다. 사용하지 않는 스타일을 정리하는 방법은 사용하지 않는 CSS 제거 방법을 참조하십시오.

  • CSS 파일 최소화: CSS 파일에서 공백, 주석, 포매팅과 같은 불필요한 문자를 제거하십시오. 최소화된 파일은 크기가 작아 로드 시간을 단축시킵니다. cssnano, PostCSS 또는 CSS 전처리기의 내장 압축 도구를 사용하여 이를 자동화할 수 있습니다.
  • 사용하지 않는 CSS 제거: 웹페이지에서 사용되지 않는 CSS 코드를 식별하고 제거하십시오. 브라우저가 다운로드하고 파싱해야 하는 데이터 양을 줄여 성능을 개선합니다. PurgeCSS나 Chrome DevTools Coverage 탭과 같은 도구는 사용하지 않는 CSS를 찾는 데 도움이 됩니다.
  • Critical CSS 인라인화: 초기 페이지 콘텐츠 렌더링에 필수적인 스타일을 HTML에 직접 제공하여 페인트 메트릭을 개선하십시오. 신규 방문자에게만 critical CSS를 제공하고, 재방문자에게는 캐시된 외부 스타일시트를 사용하는 것을 고려하십시오. 이 기법은 외부 스타일시트를 가져오는 데 필요한 왕복 시간을 없애 FCP를 줄일 수 있습니다.
  • CSS 파일 크기를 균등하게 분배: 모든 CSS를 하나의 파일로 결합하는 것이 효율적으로 보일 수 있지만, 너무 큰 파일은 다운로드 속도를 늦출 수 있습니다. 로딩을 최적화하고 브라우저가 스타일을 점진적으로 처리할 수 있도록, CSS를 더 균등한 크기 분포(각 10~15KB)의 작은 파일로 분할하는 것을 고려하십시오.
  • 화면 밖 스타일 비동기 로드: 초기 viewport 밖의 요소에 적용되는 스타일의 경우, media="print" onload="this.media='all'" 패턴을 통한 비동기 로드를 고려하십시오. 이는 브라우저가 페이지의 초기 렌더링을 차단하지 않고 다른 리소스와 병렬로 해당 스타일을 가져올 수 있게 합니다.

리소스 힌트 최적화

리소스 힌트는 중요 리소스의 다운로드 우선순위를 지정하는 데 도움을 줍니다. 사전 로드된 리소스는 일반적으로 다운로드 대기열에 추가되며 사전 로드하지 않았을 때보다 브라우저에서 훨씬 일찍 사용할 수 있습니다. 리소스 힌트를 효과적으로 사용하면 LCP 리소스 로드 지연을 크게 줄일 수 있습니다. 고급 구현 방법에 대해서는 103 Early Hints를 읽어보십시오.

  • 중요하지 않은 리소스 힌트 제거: 초기 페이지 로드에 필수적이지 않은 리소스의 사전 로드 힌트를 제거하십시오. 이렇게 하면 제한된 초기 대역폭 리소스를 두고 경쟁하는 불필요한 다운로드나 네트워크 연결을 방지할 수 있습니다. 불필요한 사전 로드는 중요한 리소스에 사용할 수 있는 대역폭을 소모합니다.
  • 주요 도메인에 Preconnect: 중요한 도메인(예: 콘텐츠 전송 네트워크 또는 폰트 제공자)에 일찍 연결을 설정하십시오. 이는 DNS, TCP, TLS 핸드셰이크를 사전에 완료하여 해당 도메인에서 중요 리소스 다운로드 속도를 높입니다. 중요한 서드파티 origin에는 <link rel="preconnect" href="https://example.com">을 사용하십시오.
  • Preconnect의 대안으로 DNS prefetch 고려: Preconnect와 유사하게 DNS prefetch는 브라우저에 잠재적인 연결을 암시합니다. 하지만 Preconnect는 전체 연결 설정을 우선시하는 반면, DNS prefetch는 브라우저에 도메인 이름만 미리 확인하도록 지시합니다. Preconnect의 전체 연결 오버헤드가 정당하지 않은 경우 <link rel="dns-prefetch">를 사용하십시오.
  • LCP 요소 사전 로드: LCP는 메인 콘텐츠가 로드되는 데 걸리는 시간을 측정합니다. LCP 요소를 사전 로드하면 브라우저에 이 중요 리소스를 우선적으로 다운로드하도록 지시하여 사용자가 메인 콘텐츠를 보는 데 걸리는 시간을 단축합니다. 이는 CSS에서 참조하거나 JavaScript를 통해 로드하는 이미지에 특히 중요합니다.
  • 주요 폰트 사전 로드: 주요 폰트를 사전 로드하면 브라우저가 조기에 가져올 수 있어 텍스트 표시 지연을 방지하고 폰트 교체로 인해 발생하는 layout shift를 개선할 수 있습니다. 가장 중요한 서체에 <link rel="preload" as="font" type="font/woff2" crossorigin>를 사용하십시오.
  • 리소스 힌트로 103 Early Hints 선호: 103 Early Hints HTTP 상태 코드는 서버가 전체 응답을 준비하기 전에 리소스 힌트를 보낼 수 있게 해줍니다. 서버가 103을 지원하지 않는다면 Link 응답 헤더를 대신 사용하십시오. 헤더를 사용할 수 없는 경우 fallback으로 페이지의 <head><link> 요소를 추가하십시오. 힌트를 더 일찍 전달할수록 리소스를 더 빨리 발견할 수 있습니다.
  • CSS 파일이 발견하기 전에 폰트 사전 로드: CSS에서 참조된 폰트는 CSS 파일이 다운로드되고 파싱된 후에야 발견됩니다. HTML <head>에서 직접 폰트를 사전 로드하면 CSS 파싱에 대한 의존성을 없애고 폰트를 병렬로 로드할 수 있어 FCP와 layout shift 위험을 모두 줄일 수 있습니다.

아이콘 최적화

아이콘을 최적화하지 않으면 페이지에 상당한 용량이 추가될 수 있습니다. 대형 인라인 SVG 아이콘은 HTML을 팽창시키고 아이콘 폰트는 수천 개의 사용하지 않는 글리프를 포함하는 경우가 많습니다. 아이콘 최적화는 LCP(HTML/CSS 용량 감소) 및 CLS(적절한 크기 예약) 모두에 영향을 미칩니다.

  • HTML에 인라인 SVG 아이콘 사용 피하기: 대형 SVG 아이콘을 인라인으로 넣으면 HTML 코드 크기가 늘어나고 페이지 로드 속도가 느려질 수 있습니다. HTML 크기를 최소화하고 브라우저가 아이콘을 캐싱할 수 있도록 별도의 파일로 제공하거나 아이콘 폰트를 (주의해서) 사용하는 등의 대안을 고려하십시오. 외부 SVG 스프라이트 시트는 성능과 유연성 사이의 최적의 균형이 되는 경우가 많습니다.
  • 대형 아이콘 폰트 피하기: Font Awesome과 같은 대형 아이콘 세트 전체를 절대 사용하지 마십시오. 서브셋을 사용하여 최적화된 아이콘 폰트나 개별 SVG를 생성하여 웹페이지의 전체 크기를 줄이고 로드 속도를 높이십시오. 전체 Font Awesome 세트는 100KB를 넘을 수 있지만 아이콘 20개로 구성된 서브셋은 5KB 미만이 될 수 있습니다.
  • 아이콘의 너비와 높이 예약: 이미지와 마찬가지로 아이콘의 너비와 높이를 지정하면 브라우저가 공간을 예약하여 로드될 때 발생하는 layout shift를 방지하는 데 도움이 됩니다. SVG 요소에 widthheight 속성을 사용하거나 CSS에서 명시적인 크기를 설정하십시오.
  • 중요하지 않은 아이콘 세트 우선순위 낮추기: 아이콘이 페이지의 초기 렌더링에 필수적이지 않다면 더 낮은 우선순위로 로드하는 것을 고려하십시오. 이렇게 하면 핵심 콘텐츠가 먼저 로드되도록 보장하고 Core Web Vitals 메트릭에 미치는 영향을 최소화합니다. lazy loading을 사용하거나 초기 페인트 후에 아이콘 스타일시트를 비동기적으로 로드하십시오.

서버 응답 시간 최적화

Time to First Byte (TTFB)로 측정되는 서버 응답 시간은 모든 페인트 메트릭과 직접적인 관계가 있습니다. 느린 서버 응답은 뒤따르는 모든 과정을 지연시킵니다. 세부적인 최적화 전략은 TTFB 문제 진단성능을 위한 Cloudflare 구성 가이드를 살펴보십시오.

  • 빠르고 안정적인 호스팅 제공업체 사용: 강력한 인프라를 갖춘 빠른 호스팅 제공업체는 서버 응답 시간과 전반적인 웹사이트 성능을 크게 향상할 수 있습니다. 마케팅용 합성이 아닌 실제 TTFB 측정값을 사용하여 호스팅 제공업체를 벤치마킹하십시오.
  • 서버 측 코드 및 데이터베이스 쿼 최적화: 코드 실행 및 데이터베이스 쿼리 시간을 자주 기록하여 병목 현상을 찾고 전반적인 속도를 개선하십시오. 쿼리 프로파일링 및 애플리케이션 성능 모니터링(APM) 도구를 사용하여 느린 엔드포인트를 식별하십시오.
  • 캐싱 전략 구현: 브라우저 캐싱 및 서버 측 캐싱을 활용하여 자주 액세스하는 데이터를 저장하여 반복적인 데이터 검색 필요성을 줄이고 로드 시간을 개선하십시오. 전체 페이지 캐싱은 TTFB를 수 초에서 100ms 미만으로 줄일 수 있습니다. 캐시 기간 최적화에 대해 자세히 알아보십시오.
  • 개인화를 위한 클라이언트 측 또는 에지 렌더링: 전체 페이지 캐시 기능을 유지하기 위해 장바구니 개수, 로그인 상태 또는 사소한 메뉴 변경과 같은 작은 개인화 요소를 클라이언트 측이나 에지에서 렌더링하는 것을 고려하십시오. 이는 사소한 동적 요소로 인해 전체 페이지의 캐시가 무효화되는 것을 방지합니다.
  • 서버 구성 최적화: 성능을 위해 웹 서버 설정을 검토하고 조정하십시오. 여기에는 연결 keep-alive 설정, 작업자 프로세스 수, 메모리 할당 및 timeout 값이 포함됩니다. 잘못 구성된 서버는 리소스를 낭비하고 응답 시간을 늘릴 수 있습니다.
  • Content Delivery Network (CDN) 사용: CDN은 웹사이트의 정적 콘텐츠를 여러 에지 노드(서버)에 분산합니다. 이는 사용자가 콘텐츠에 액세스하는 데 필요한 물리적 거리를 줄여 글로벌 방문자의 로드 시간을 단축시킵니다. 또한 CDN은 일반적으로 자체 서버보다 더 잘 구성되어 있습니다. 실용적인 설정 단계는 Cloudflare 구성 가이드를 참조하십시오.
  • 서버 측 처리량 감소: 요청당 서버가 수행하는 작업량을 최소화하십시오. 비용이 많이 드는 연산은 미리 계산하고 효율적인 알고리즘을 사용하며, 중요하지 않은 처리는 백그라운드 작업으로 옮기십시오. 애플리케이션의 요청 수명 주기를 분석하여 불필요한 처리 단계를 찾고 제거하십시오.
  • HTTP/3 사용: HTTP/3는 Hypertext Transfer Protocol의 최신 버전입니다. HTTP/3는 HTTP/2보다 빠르고 효율적이며 HTTP/1.1보다 훨씬 빠릅니다. HTTP/3로 업그레이드하면 전반적인 페이지 로드 시간이 개선되고 3가지 Core Web Vitals 메트릭(LCP, INP, CLS)을 모두 잠재적으로 개선할 수 있습니다. 연결 시간 최적화에 대해 자세히 알아보십시오.
  • Server-Timing 헤더 설정: 이 헤더는 페이지의 각 부분이 서버에서 처리되는 데 걸리는 시간에 대한 자세한 정보를 제공합니다. 이 데이터를 통해 병목 현상과 개선 영역을 정확히 찾아낼 수 있으며, 특히 Largest Contentful Paint(LCP) 개선에 집중할 수 있습니다. Server-Timing 헤더는 Chrome DevTools의 Network 패널에서 확인할 수 있으며 CoreDash와 같은 RUM 도구를 통해 캡처할 수 있습니다.
  • 느린 데이터베이스 쿼리를 기록하고 정기적으로 최적화: 데이터베이스(MySQL, PostgreSQL, MongoDB)에서 느린 쿼리 로깅을 활성화하고 매주 로그를 검토하십시오. 인덱스 최적화, 쿼리 재구성 및 자주 발생하는 쿼리에 대한 캐싱 레이어 추가는 TTFB를 극적으로 줄일 수 있습니다.
  • GZIP 또는 Brotli 압축 사용: GZIP 또는 최신의 Brotli는 전송 전에 텍스트 기반 리소스(HTML, CSS, JavaScript)를 실시간으로 압축하여 파일 크기를 약 70% 줄입니다. Brotli는 일반적으로 GZIP보다 15~20% 더 나은 압축률을 달성합니다. 파일 크기가 작을수록 로드 시간은 단축됩니다.

상호작용 최적화

Interaction to Next Paint (INP)는 사이트가 사용자 상호작용에 얼마나 빨리 반응하는지 측정합니다. 좋지 않은 상호작용은 주로 main thread를 차단하는 JavaScript long task로 인해 발생합니다. 3단계의 INP에 대한 완벽한 분석은 입력 지연, 처리 시간, 표시 지연 가이드를 참조하십시오.

  • 무거운 스크립트에 idle-until-urgent 패턴 구현: 이 방식은 핵심 작업의 우선순위를 지정하고, 브라우저 main thread가 idle 상태가 될 때까지 중요하지 않은 JavaScript 실행을 지연시킵니다. 이를 통해 장기 실행 스크립트가 렌더링 및 사용자 상호작용과 같은 중요 작업을 차단하지 않도록 보장합니다. 중요하지 않은 작업의 일정을 예약하려면 requestIdleCallback을 사용하십시오. 처리 시간 최적화에 대해 자세히 알아보십시오.
  • main thread에 yielding하여 long task 분할: 복잡한 JavaScript 작업은 main thread를 차단하여 응답성을 지연시킬 수 있습니다. 이러한 작업을 작은 청크로 나누고 청크 사이에 main thread로 제어권을 yielding하면 브라우저가 사용자 상호작용을 처리하고 매끄러운 사용자 경험을 유지할 수 있습니다. scheduler.yield()(지원되는 경우) 또는 setTimeout(0)을 사용하여 long task를 분할하십시오. JavaScript 스크롤링을 제거하여 INP를 개선하는 방법 가이드를 확인하십시오.
  • 입력 후 즉각적인 피드백 제공: 사용자는 웹사이트와 상호작용한 후 즉각적인 반응을 기대합니다. 백그라운드에서 오랜 작업이 처리되는 동안에도 시각적 단서를 제공하거나 사용자 입력을 즉시 인지하게 하십시오. 즉각적인 시각적 피드백을 위해 CSS transition과 :active 가상 클래스를 사용하십시오. 이는 상호작용하는 느낌을 유지하고 웹사이트가 멈춘 것처럼 느끼는 것을 방지합니다.
  • 스크롤 및 터치에 passive 이벤트 리스너 사용: 스크롤 및 터치 이벤트 리스너에 { passive: true }를 추가하십시오. passive 리스너는 브라우저에게 핸들러가 절대 preventDefault()를 호출하지 않을 것임을 알려주어 JavaScript를 기다리지 않고 즉시 스크롤을 시작할 수 있게 합니다. 이는 모바일 기기에서 특히 큰 영향을 미치며 스크롤 관련 상호작용의 INP를 직접적으로 개선합니다.

Core Web Vitals 모니터링

Core Web Vitals를 지속적으로 모니터링하는 것은 성능 저하를 조기에 발견하고 최적화가 예상한 효과를 내는지 검증하는 데 필수적입니다. 정확한 상황 파악을 위해 lab data, field data, 그리고 RUM을 결합하여 사용하십시오.

  • Lighthouse 정기 점검: Lighthouse는 웹페이지의 성능 문제를 파악하는 데 도움을 주는 Google의 무료 오픈소스 감사 도구입니다. Lighthouse는 실제 사용자 환경에서 직접 Core Web Vitals를 측정하지는 않지만, 통제되고 표준화된 조건에서 웹사이트를 주기적으로 테스트하고 비교하기 위한 훌륭한 도구입니다. 배포 전에 성능 저하를 잡기 위해 CI/CD 파이프라인에서 Lighthouse를 실행하십시오.
  • 정기적인 CrUX 과거 데이터 확인: CrUX(Chrome User Experience Report)는 실제 성능 데이터를 제공하는 Google의 공개 데이터 세트입니다. CrUX는 Google이 귀하의 Core Web Vitals 통과 여부를 결정할 때 사용하는 데이터 소스입니다. 과거 데이터를 사용하여 성능 저하를 빠르게 발견하십시오. PageSpeed Insights, CrUX 대시보드 또는 CrUX API를 통해 CrUX 데이터에 액세스할 수 있습니다.
  • RUM 추적 설정: RUM은 웹사이트에서의 실제 사용자 경험을 추적하는 것을 말합니다. RUM 도구는 다양한 위치와 기기에서 방문자의 페이지가 실제로 로드되는 데 걸리는 시간에 대한 데이터를 수집합니다. 이는 Lighthouse 및 CrUX의 시뮬레이션 데이터를 보완하여 실제 성능에 대한 귀중한 통찰력을 제공합니다. 자세한 Core Web Vitals 어트리뷰션 데이터를 위한 RUM 추적 도구로 CoreDash를 추천합니다.
  • 성능 예산 설정: 성능 예산은 각 메트릭에 대해 특정한 성능 목표(예: LCP 2.5초 미만, INP 200ms 미만, CLS 0.1 미만)를 설정합니다. 이는 최적화 작업을 안내하는 벤치마크 역할을 합니다. 설정한 예산 대비 성능을 정기적으로 점검하면 즉각적인 주의가 필요한 영역을 파악하고 최적화의 우선순위를 정하는 데 도움이 됩니다.
  • 세분화(segmentation) 사용: 세분화를 사용하여 가장 가치 있는 방문자 유형과 다양한 페이지 유형을 추적하십시오. 그렇지 않으면 방대한 트래픽으로 인해 특정 중요 그룹에 영향을 미치는 성능 문제가 가려질 수 있습니다. 숨겨진 문제를 찾아내려면 기기 유형, 연결 속도, 지역 및 페이지 템플릿별로 분류하십시오.

Critical Rendering Path 최적화

Critical rendering path는 브라우저가 HTML, CSS 및 JavaScript를 눈에 보이는 픽셀로 변환하기 위해 거치는 일련의 단계입니다. 이 경로를 최적화하면 First Contentful PaintLCP 요소 렌더링 지연이 직접적으로 개선됩니다. 과도한 DOM 크기를 방지하는 방법도 참조하십시오.

  • 중요 리소스 수 최소화: 모든 render blocking 리소스(CSS 및 동기식 JavaScript)는 브라우저가 페인트하기 전에 다운로드하고 처리해야 합니다. 중요하지 않은 스크립트를 지연시키고 중요하지 않은 스타일시트를 비동기로 로드하여 중요 리소스 수를 줄이십시오.
  • 리소스 로딩 순서 최적화: 중요 CSS와 폰트가 먼저 로드된 다음 above-the-fold 이미지가, 그 뒤에 지연된 스크립트가 로드되도록 하십시오. fetchpriority 속성과 리소스 우선순위 지정 힌트를 사용하여 브라우저에 중요도를 전달하십시오.
  • DOM 트리 깊이 줄이기: 깊게 중첩된 DOM 트리는 스타일 계산 시간과 레이아웃 작업을 늘립니다. 가능하면 최대 32레벨 깊이 및 총 1,500개 미만의 DOM 요소를 목표로 하십시오. 더 평평한 DOM 구조는 페인트 성능과 INP 표시 지연을 모두 개선합니다.
  • 요소 태그 및 속성보다 클래스와 ID 선호: p.important 대신 .important를 사용하십시오. 이렇게 하면 브라우저가 스타일 매칭을 위해 해당 유형의 모든 요소를 검색할 필요가 줄어들어 더 빠른 스타일 재계산이 이루어집니다.
  • 선택자 깊게 중첩하지 않기: CSS 선택자를 깊게 중첩할수록 브라우저가 수행해야 하는 계산이 늘어납니다. 중첩을 줄이도록 HTML을 재구성하거나 요소에 더 가까운 명확한 클래스를 사용해 보십시오. 선택자 깊이를 최대 3레벨로 제한하십시오.
  • 하위 선택자 최소화: .container > .content와 같은 선택자는 브라우저가 컨테이너 내의 모든 요소를 검사하도록 강제합니다. 가능하다면 콘텐츠 요소에 더 직접적인 클래스를 사용하여 선택자 매칭 속도를 높이십시오.
  • 동일한 스타일을 가진 선택자 통합: 여러 요소가 동일한 스타일을 공유하는 경우, 유지보수를 용이하게 하고 CSS 출력을 줄이기 위해 이를 단일 클래스로 그룹화하거나 BEM(Block Element Modifier) 명명 규칙을 사용하십시오.

쿠키 동의 최적화

쿠키 동의 배너는 GDPR 및 유사한 규정에 의해 요구되지만 신중하게 구현하지 않으면 Core Web Vitals에 큰 영향을 미칠 수 있습니다. 잘못 로드된 동의 배너는 LCP를 지연시키고 CLS를 유발하며 INP를 증가시킬 수 있습니다. 자세한 내용은 Core Web Vitals를 위한 서드파티 위젯 최적화를 읽어보십시오.

  • 동적 페이지에 대해 서버 측 쿠키 동의 고려: 동적으로 서버 측에서 렌더링되는 페이지의 경우, 초기 HTML 응답에서 동의 배너를 렌더링하는 서버 측 솔루션을 구현하는 것이 별도의 JavaScript 기반 솔루션을 로드하는 것보다 종종 더 빠릅니다. 이는 추가 네트워크 요청 및 스크립트 평가 오버헤드를 없애줍니다.
  • 캐시된 페이지에서 쿠키 동의 스크립트 비동기 로드: 캐시된 페이지의 경우, 쿠키 동의 스크립트를 비동기로 로드하고 스크립트에 fetchpriority="high"를 추가하는 것을 고려하여 사용자 상호작용 전에 표시될 수 있을 만큼 일찍 로드되도록 하십시오.
  • LCP 간섭을 피하기 위해 동의 문구를 짧게 유지: 긴 쿠키 알림 텍스트는 브라우저가 화면에서 가장 큰 텍스트 블록을 잠재적 LCP 후보로 간주하기 때문에 LCP 요소를 차지할 수 있습니다. 텍스트를 더 짧게 쓰거나 표시 영역이 더 작은 여러 단락으로 나누는 것을 고려하십시오.
  • 쿠키 알림 스크립트 자체 호스팅: 가능한 한 쿠키 알림 스크립트 및 스타일시트를 캐시하고 자체 호스팅하십시오. 이는 서드파티 동의 관리 플랫폼에 대한 DNS 조회 및 연결 오버헤드를 제거하고 로딩 동작에 대한 완전한 제어권을 부여합니다.

Single Page Application 최적화

React, Vue, Angular 또는 유사한 프레임워크로 구축된 Single Page Application(SPA)은 독특한 Core Web Vitals 문제에 직면합니다. 클라이언트 측 렌더링은 FCPLCP를 모두 지연시킬 수 있으며, hydration은 INP를 차단할 수 있습니다.

  • 항상 서버 측 렌더링 또는 사전 렌더링(prerendering) 사용: 클라이언트 측 렌더링에만 의존하는 SPA는 콘텐츠가 표시되기 전에 브라우저가 JavaScript를 다운로드하고 파싱하고 실행하도록 강제합니다. 브라우저가 즉시 페인트할 수 있는 초기 HTML을 제공하기 위해 SSR(Next.js, Nuxt, SvelteKit)이나 정적 사전 렌더링을 사용하십시오.
  • 동적 생성보다 정적 사전 렌더링 선호: 빌드 시간에 생성된 정적 사전 렌더링은 서버 측 처리 없이 CDN에서 직접 제공할 수 있으므로 동적으로 생성된 사전 렌더링보다 훨씬 빠릅니다. 요청별 데이터가 필요하지 않은 페이지에는 정적 생성을 사용하십시오.
  • Hydration 후 서드파티 스크립트 로드: Hydration 동안 프레임워크는 페이지를 상호작용 가능하게 만들기 위해 이미 상당한 main thread 시간을 소모하고 있습니다. 서드파티 스크립트를 동시에 로드하면 문제가 복잡해지고 입력 지연이 악화됩니다. Hydration 과정이 완료될 때까지 중요하지 않은 모든 스크립트를 지연시키십시오.

과도한 DOM 크기 방지

대규모 DOM(1,500개 이상의 요소 또는 32레벨을 초과하는 깊이)은 메모리 사용량을 늘리고 스타일 계산을 늦추며 큰 비용이 드는 레이아웃 리플로우(reflow)를 유발합니다. 이는 INP 표시 지연 및 페인트 메트릭 모두에 직접적인 영향을 미칩니다. 과도한 DOM 크기 수정 방법을 참조하십시오.

  • 불필요한 DOM 요소 줄이기: 스타일링이나 구조적 목적이 없는 래퍼 요소가 있는지 HTML을 감사하십시오. 깊게 중첩된 <div> 구조를 시맨틱 HTML 요소로 교체하십시오. 활성화된 DOM을 작게 유지하기 위해 react-window 또는 virtual-scroller와 같은 라이브러리로 긴 목록을 가상화하는 것을 고려하십시오.
  • 효율적인 JavaScript 및 CSS 선택자 사용: 복잡한 CSS 선택자와 JavaScript DOM 쿼리(광범위한 패턴을 가진 querySelectorAll 등)는 DOM 크기가 커짐에 따라 기하급수적으로 느려집니다. 명확한 클래스 선택자를 사용하고 가능할 때마다 DOM 쿼리의 범위를 하위 트리로 제한하십시오.
  • 화면 밖 콘텐츠에 content-visibility: auto 사용: CSS content-visibility: auto 속성은 화면 밖의 요소가 스크롤되어 보일 때까지 브라우저가 렌더링을 건너뛰도록 지시합니다. 이는 긴 콘텐츠 섹션이 있는 페이지의 초기 렌더링 작업을 크게 줄일 수 있습니다.

API 요청 최적화

렌더링을 차단하거나 콘텐츠를 지연시키는 API 요청은 LCPTTFB에 부정적인 영향을 미칠 수 있습니다. 클라이언트 측 데이터 패칭은 Single Page Application에서 LCP가 느려지는 흔한 원인입니다.

  • API 요청 수 최소화: 각 API 요청은 전반적인 페이지 로드 시간을 늘립니다. 웹사이트 기능을 평가하고 초기 콘텐츠를 렌더링하는 데 필요한 API 요청 수를 줄일 기회를 찾으십시오. 데이터 배칭(여러 요청을 하나로 결합) 및 GraphQL과 같은 기법으로 왕복을 줄일 수 있습니다.
  • 효율적이고 최적화된 API 사용: API 자체의 설계와 구현이 성능에 영향을 미칠 수 있습니다. 속도와 효율성을 위해 잘 설계된 최적화된 API를 사용하고 있는지 확인하십시오. API 측에 캐싱 메커니즘을 구현하여 자주 요청되는 데이터의 응답 시간을 단축하십시오.
  • 중요 API 요청 사전 로드: 이미지와 같은 중요 리소스를 사전 로드하는 것과 유사하게, 필수 API 요청을 사전 로드하면 체감 성능을 크게 향상할 수 있습니다. <link rel="preload" as="fetch">를 사용하여 브라우저가 중요한 API를 일찍 가져오도록 지시하여, 초기 콘텐츠 렌더링에 필요할 때의 지연을 최소화하십시오. 더 많은 기법은 리소스 우선순위 지정 가이드를 참조하십시오.

채팅 위젯 최적화

채팅 위젯은 layout shift의 흔한 원인이며, 일찍 로드될 경우 LCP에 문제를 일으킬 수도 있습니다. 단계별 접근 방법은 완벽한 Core Web Vitals를 갖춘 채팅 위젯 구현 방법을 읽어보십시오.

  • 메인 콘텐츠가 로드된 후 채팅 위젯 로드: 인터넷 역사상 페이지의 메인 콘텐츠가 로드되기도 전에 채팅이 필요한 사람은 없었습니다. requestIdleCallback이나 스크롤 기반 트리거를 사용하여 페이지의 초기 렌더링이 완료될 때까지 채팅 위젯 초기화를 지연시키십시오.
  • 채팅 위젯 레이아웃 변경(layout shift) 방지: 채팅 위젯이 layout shift를 유발한다면 페이지에 완전히 렌더링될 때까지 opacity: 0으로 숨기는 것이 좋습니다. 이는 위젯이 백그라운드에서 배치되도록 하여 눈에 보이는 콘텐츠가 튀는 것을 방지합니다. CSS transition을 사용하여 위젯이 부드럽게 나타나도록 하십시오.
  • 가벼운 채팅 위젯 제공업체 선택: 여러 곳을 비교해 보십시오. 일부 채팅 위젯은 다른 것들보다 훨씬 더 가볍고 Core Web Vitals 문제를 덜 일으킵니다. 도입을 결정하기 전에 각 제공업체의 JavaScript 번들 크기, 네트워크 요청 수, INP 영향을 비교하십시오.

Service Worker 성능 최적화

서비스 워커는 자산 및 전체 페이지 응답까지 캐시하여 재방문자의 TTFB를 줄임으로써 재방문 성능을 크게 향상할 수 있습니다. 그러나 잘못 구현된 서비스 워커는 오히려 탐색 속도를 늦출 수 있습니다. 캐시 기간 최적화에 대해 자세히 알아보십시오.

  • 서비스 워커에 중요 리소스 캐시: CSS, JavaScript, 폰트 및 이미지와 같은 정적 자산에 대해 cache-first 전략을 사용하십시오. 이렇게 하면 재방문자가 로컬 캐시에서 사이트를 거의 즉각적으로 로드할 수 있습니다. 서비스 워커 설치(install) 이벤트 중에 가장 중요한 리소스를 사전 캐시하십시오.
  • 서비스 워커 코드 최적화: 서비스 워커를 가볍고 효율적으로 유지하십시오. 복잡한 라우팅 로직, event.waitUntil()의 과도한 사용, 설치를 늦추는 거대한 사전 캐시 매니페스트를 피하십시오. 자주 변경되지만 즉각적인 최신 상태가 필요하지 않은 리소스에 대해서는 stale-while-revalidate 패턴을 사용하십시오.

비디오 콘텐츠 최적화

비디오 요소는 viewport에서 볼 수 있는 가장 큰 콘텐츠일 경우 LCP 요소가 될 수 있습니다. 최적화되지 않은 대용량 비디오는 다른 중요 리소스와 대역폭을 두고 경쟁하기도 합니다.

  • 비디오 압축 및 최적화: 적절한 품질 설정과 함께 H.264, VP9 또는 AV1과 같은 최신 코덱을 사용하십시오. 비디오 해상도를 최대 표시 크기에 맞춰 줄이십시오. 가로 400px로 표시되는 비디오를 1920px로 인코딩할 필요는 없습니다. 품질 대비 파일 크기 비율을 최상으로 유지하려면 2패스(two-pass) 인코딩을 사용하십시오.
  • 비디오에 lazy loading 사용: 스크롤해야 보이는 비디오의 경우 <iframe> 요소에 loading="lazy" 속성을 사용하거나 Intersection Observer API로 비디오 로드를 지연시키십시오. 자동 재생되는 배경 비디오를 포스터 이미지로 교체하고 사용자가 근처로 스크롤할 때만 비디오를 로드하십시오.
  • 빠른 CDN에 비디오 호스팅: 비디오 파일은 크기가 커서 CDN 배포를 통해 큰 이점을 얻을 수 있습니다. 적응형 비트 전송률(adaptive bitrate) 스트리밍, 지리적 분산, 최적화된 전송을 제공하는 전용 비디오 CDN 또는 호스팅 서비스(예: Cloudflare Stream, Mux, Bunny.net)를 사용하십시오.
  • 비디오 요소에 포스터 이미지 사용: <video> 요소에 항상 poster 속성을 설정하십시오. 포스터 이미지는 비디오가 로드되는 동안 브라우저가 즉시 페인트할 무언가를 제공하여 LCP 요소의 역할을 할 수 있습니다. 다른 LCP 이미지와 마찬가지로 포스터 이미지를 최적화하십시오.

About the author

Arjen Karel is a web performance consultant and the creator of CoreDash, a Real User Monitoring platform that tracks Core Web Vitals data across hundreds of sites. He also built the Core Web Vitals Visualizer Chrome extension. He has helped clients achieve passing Core Web Vitals scores on over 925,000 mobile URLs.

보고서 말고 코드를 씁니다.

1~2 스프린트 동안 팀에 합류해서 모니터링까지 세팅해둡니다. 제가 빠진 뒤에도 지표가 계속 초록으로 유지되도록.

연락 주세요
궁극의 Core Web Vitals 체크리스트 (2026) Core Web Vitals 궁극의 Core Web Vitals 체크리스트 (2026)