Largest Contentful Paint (LCP)

브라우저 지원

  • 77
  • 79
  • 122
  • x

소스

콘텐츠가 포함된 최대 페인트 (LCP)는 인지된 로드 속도를 측정하는 안정적인 Core Web Vitals 측정항목입니다. 페이지 로드 타임라인에서 페이지의 주요 콘텐츠가 로드되었을 가능성이 있는 지점을 표시합니다. LCP가 빠르면 사용자에게 페이지가 유용하다는 확신을 줄 수 있습니다.

이전에는 웹 개발자가 웹페이지의 주요 콘텐츠가 얼마나 빨리 로드되고 사용자에게 표시되는지 측정하는 것이 어려웠습니다. load 또는 DOMContentLoaded와 같은 이전 측정항목은 제대로 작동하지 않습니다. 사용자에게 화면에 표시되는 것과 반드시 일치하지 않기 때문입니다. 또한 콘텐츠가 포함된 첫 페인트 (FCP)와 같은 새로운 사용자 중심의 성능 측정항목은 로드 환경의 맨 처음만 캡처합니다. 페이지에 스플래시 화면이 표시되거나 로드 표시기가 표시된다면 이 시점은 사용자와 크게 관련이 없습니다.

이전에는 초기 페인트 후 더 많은 로드 환경을 캡처하는 데 도움이 되도록 첫 번째 의미 있는 페인트(FMP)속도 색인 (SI)(모두 Lighthouse에서 사용 가능)과 같은 성능 측정항목을 권장했지만 이러한 측정항목은 복잡하고 설명하기 어렵고 잘못된 경우가 많아 페이지의 주요 콘텐츠가 로드된 시점을 식별하지 못합니다.

W3C Web Performance Working Group의 토론 및 Google에서 진행한 연구에 따르면 페이지의 주요 콘텐츠가 로드되는 시점을 더 정확하게 측정하는 방법은 가장 큰 요소가 렌더링되는 시점을 확인하는 것입니다.

LCP란 무엇인가요?

LCP는 사용자가 처음 페이지로 이동한 시점을 기준으로 표시 영역에 표시되는 가장 큰 이미지 또는 텍스트 블록의 렌더링 시간을 보고합니다.

좋은 LCP 점수란 무엇인가요?

우수한 사용자 환경을 제공하려면 사이트의 LCP가 2.5초 이하여야 합니다. 대부분의 사용자가 이 목표에 도달하도록 하려면 모바일 및 데스크톱 기기로 분류된 페이지 로드의 75번째 백분위수를 측정하기에 좋습니다.

올바른 LCP 값은 2.5초 이하이고, 좋지 않은 값은 4.0초보다 큽니다. 그 사이의 값은 개선이 필요합니다.
올바른 LCP 값은 2.5초 이하입니다.

고려되는 요소는 무엇인가요?

Largest Contentful Paint API에 지정된 대로 최대 Contentful Paint에 고려되는 요소 유형은 다음과 같습니다.

이 제한된 집합으로 요소를 제한한 것은 복잡성을 줄이기 위해 의도된 것입니다. 향후 더 많은 연구가 진행됨에 따라 추가 요소 (예: 전체 <svg> 지원)가 추가될 수 있습니다.

LCP 측정에서는 일부 요소만 고려할 뿐 아니라 휴리스틱을 사용하여 사용자가 '콘텐츠가 없는' 것으로 간주할 가능성이 있는 특정 요소를 제외합니다. Chromium 기반 브라우저의 경우 다음이 포함됩니다.

  • 불투명도가 0인 요소로, 사용자에게 표시되지 않습니다.
  • 전체 표시 영역을 덮는 요소로, 배경 요소일 가능성이 높습니다.
  • 페이지의 실제 콘텐츠를 반영하지 않으며 엔트로피가 낮은 자리표시자 이미지 또는 기타 이미지

브라우저는 가장 큰 콘텐츠가 포함된 요소가 무엇인지에 대한 사용자의 기대치를 충족하기 위해 이러한 휴리스틱을 지속적으로 개선할 가능성이 높습니다.

이러한 '콘텐츠가 포함된' 휴리스틱은 LCP 후보에 적합하지 않더라도 자리표시자 이미지 또는 전체 표시 영역 이미지와 같은 요소의 일부를 고려할 수 있는 FCP에서 사용하는 것과 다릅니다. 두 측정항목 모두 이름에 'contentful'이 사용되지만 이 측정항목의 목표는 다릅니다. FCP는 모든 콘텐츠가 화면에 그려질 때 측정하는 반면 LCP는 기본 콘텐츠가 페인트될 때 측정합니다.

요소의 크기는 어떻게 결정되나요?

LCP에 관해 보고된 요소의 크기는 일반적으로 표시 영역 내에서 사용자에게 표시되는 크기입니다. 요소가 표시 영역 밖으로 확장되거나 요소가 잘리거나 보이지 않는 overflow가 있는 경우 이러한 부분은 요소 크기에 포함되지 않습니다.

기본 크기에서 크기가 조절된 이미지 요소의 경우 보고되는 크기는 표시 크기 또는 고유 크기 중 더 작은 쪽입니다.

텍스트 요소의 경우 LCP는 모든 텍스트 노드를 포함할 수 있는 가장 작은 직사각형만 고려합니다.

모든 요소의 LCP에서는 CSS를 사용하여 적용된 여백, 패딩 또는 테두리를 고려하지 않습니다.

LCP는 언제 보고되나요?

웹페이지는 단계적으로 로드되는 경우가 많으므로 페이지에서 가장 큰 요소가 로드되는 동안 변경될 수 있습니다.

이러한 변경 가능성을 처리하기 위해 브라우저는 브라우저가 첫 번째 프레임을 칠하는 즉시 콘텐츠가 포함된 가장 큰 요소를 식별하는 largest-contentful-paint 유형의 PerformanceEntry를 전달합니다. 후속 프레임을 렌더링한 후에는 콘텐츠가 포함된 가장 큰 요소가 변경될 때마다 다른 PerformanceEntry를 전달합니다.

예를 들어 텍스트와 히어로 이미지가 있는 페이지에서 브라우저는 처음에 텍스트만 렌더링할 수 있으며 브라우저는 element 속성이 <p> 또는 <h1>를 참조하는 largest-contentful-paint 항목을 전달합니다. 히어로 이미지의 로드가 완료되면 <img>를 참조하는 element 속성과 함께 두 번째 largest-contentful-paint 항목이 전달됩니다.

요소는 렌더링되고 사용자에게 표시된 후에만 콘텐츠가 포함된 가장 큰 요소로 간주될 수 있습니다. 아직 로드되지 않은 이미지는 '렌더링된' 것으로 간주되지 않습니다. 또한 글꼴 차단 기간에는 웹 글꼴을 사용하는 텍스트 노드도 없습니다. 이러한 경우 작은 요소가 가장 큰 콘텐츠가 포함된 요소로 보고될 수 있지만 큰 요소의 렌더링이 완료되는 즉시 다른 PerformanceEntry가 생성됩니다.

페이지에서 늦게 로드되는 이미지와 글꼴 외에, 새 콘텐츠를 사용할 수 있게 되면 DOM에 새 요소를 추가할 수도 있습니다. 이러한 새 요소 중 하나라도 이전에 가장 큰 콘텐츠가 포함된 요소보다 크면 새 PerformanceEntry가 생성됩니다.

가장 큰 콘텐츠가 포함된 요소가 표시 영역 또는 DOM에서 삭제되더라도 더 큰 요소가 렌더링되지 않는 한 이 요소는 콘텐츠가 포함된 요소 중 가장 큰 요소로 유지됩니다.

사용자 상호작용으로 인해(특히 스크롤할 때) 사용자에게 표시되는 항목이 변경되는 경우가 많기 때문에 사용자가 탭, 스크롤 또는 키 누름을 통해 페이지와 상호작용하는 즉시 브라우저에서 새 항목 보고를 중지합니다.

분석을 위해 가장 최근에 전달된 PerformanceEntry만 분석 서비스에 보고합니다.

로드 시간과 렌더링 시간 비교

보안상의 이유로 Timing-Allow-Origin 헤더가 없는 교차 출처 이미지의 경우 이미지의 렌더링 타임스탬프가 노출되지 않습니다. 대신 다른 API에서 이미 노출하는 로드 시간만 사용할 수 있습니다.

이로 인해 웹 API에서 LCP를 FCP보다 일찍 보고하는 것이 불가능해 보이는 상황이 발생할 수 있습니다. 이는 보안 제한 때문이며 실제로 상황을 나타내지 않습니다.

가능하면 항상 Timing-Allow-Origin 헤더를 설정하여 측정항목의 정확성을 높이는 것이 좋습니다.

요소 레이아웃과 크기 변경은 어떻게 처리되나요?

새 성능 항목을 계산하고 전달하는 성능 오버헤드를 낮게 유지하기 위해 요소의 크기나 위치를 변경해도 새 LCP 후보가 생성되지 않습니다. 표시 영역에서 요소의 초기 크기와 위치만 고려됩니다.

즉, 처음에 화면 밖으로 렌더링된 후 화면에서 전환되는 이미지는 보고되지 않을 수 있습니다. 또한 처음에 표시 영역에 렌더링되었다가 시야 밖으로 밀려나는 요소가 여전히 초기 표시 영역 크기를 보고한다는 것을 의미합니다.

다음은 몇 가지 인기 웹사이트에서 최대 콘텐츠 렌더링이 발생하는 경우의 예입니다.

cnn.com의 최대 콘텐츠 렌더링 시간 타임라인
cnn.com의 LCP 타임라인
Techcrunch.com의 최대 콘텐츠 렌더링 시간 타임라인
techcrunch.com의 LCP 타임라인

두 타임라인 모두에서 콘텐츠가 로드될 때 가장 큰 요소 (녹색으로 강조표시됨)가 변경됩니다. 첫 번째 예에서는 DOM에 새 콘텐츠가 추가되어 가장 큰 요소를 변경합니다. 두 번째 예에서는 레이아웃이 변경되고 표시 영역에서 가장 큰 이전 콘텐츠 요소가 삭제됩니다.

지연 로드 콘텐츠는 이미 페이지에 있는 콘텐츠보다 큰 경우가 많지만 반드시 그런 것은 아닙니다. 다음 두 예는 페이지가 완전히 로드되기 전에 발생하는 LCP를 보여줍니다

instagram.com의 최대 콘텐츠 렌더링 시간 타임라인
instagram.com의 LCP 타임라인
google.com의 최대 콘텐츠 렌더링 시간 타임라인
google.com의 LCP 타임라인

첫 번째 예에서 Instagram 로고는 상대적으로 일찍 로드되며 다른 콘텐츠가 추가되더라도 가장 큰 요소로 유지됩니다. Google 검색결과 페이지 예에서 가장 큰 요소는 이미지 또는 로고 로드가 완료되기 전에 표시되는 텍스트 단락입니다. 각 개별 이미지는 이 단락보다 작기 때문에 로드 프로세스 전반에 걸쳐 가장 큰 요소로 유지됩니다.

LCP 측정 방법

LCP는 실험실 또는 현장에서 측정할 수 있으며 다음 도구에서 사용할 수 있습니다.

현장 도구

실습 도구

자바스크립트에서 LCP 측정

JavaScript에서 LCP를 측정하려면 최대 Contentful Paint API를 사용하세요. 다음 예는 largest-contentful-paint 항목을 수신 대기하고 콘솔에 로깅하는 PerformanceObserver를 만드는 방법을 보여줍니다.

new PerformanceObserver((entryList) => {
  for (const entry of entryList.getEntries()) {
    console.log('LCP candidate:', entry.startTime, entry);
  }
}).observe({type: 'largest-contentful-paint', buffered: true});

이전 예에서 로깅된 각 largest-contentful-paint 항목은 현재 LCP 후보를 나타냅니다. 일반적으로 마지막으로 내보낸 항목의 startTime 값은 LCP 값입니다. 그러나 모든 largest-contentful-paint 항목이 LCP를 측정하는 데 유효한 것은 아닙니다.

다음 섹션에는 API 보고와 측정항목 계산 방법의 차이점이 나와 있습니다.

측정항목과 API의 차이점

  • API는 백그라운드 탭에 로드된 페이지의 largest-contentful-paint 항목을 전달하지만 LCP를 계산할 때 이러한 페이지를 무시해야 합니다.
  • API는 페이지가 백그라운드로 전환된 후에도 largest-contentful-paint 항목을 계속 전달하지만 LCP를 계산할 때 이러한 항목을 무시해야 합니다. 요소는 페이지가 전체 시간 동안 포그라운드에 있었던 경우에만 고려할 수 있습니다.
  • 페이지가 뒤로-앞으로 캐시에서 복원될 때 API가 largest-contentful-paint 항목을 보고하지 않지만, 이러한 경우에는 사용자가 이를 고유한 페이지 방문으로 경험하기 때문에 LCP를 측정해야 합니다.
  • API는 iframe 내의 요소를 고려하지 않지만 측정항목은 페이지 사용자 환경의 일부이므로 iframe 내의 요소를 고려합니다. iframe 내에 LCP가 있는 페이지(예: 삽입된 동영상의 포스터 이미지)에서 이는 CrUX와 RUM의 차이로 표시됩니다. LCP를 제대로 측정하려면 iframe을 포함해야 합니다. 하위 프레임은 API를 사용하여 집계를 위해 largest-contentful-paint 항목을 상위 프레임에 보고할 수 있습니다.
  • API는 탐색 시작부터 LCP를 측정합니다. 사전 렌더링된 페이지의 경우 사용자가 경험하는 LCP 시간에 해당하므로 activationStart의 LCP를 대신 측정합니다.

개발자는 이러한 미묘한 차이점을 모두 기억하는 대신 web-vitals JavaScript 라이브러리를 사용하여 이러한 차이점 대부분을 처리하는 LCP를 측정하는 것이 좋습니다. iframe 문제는 다루지 않습니다.

import {onLCP} from 'web-vitals';

// Measure and log LCP as soon as it's available.
onLCP(console.log);

JavaScript에서 LCP를 측정하는 방법에 관한 전체 예는 onLCP() 소스 코드를 참고하세요.

가장 큰 요소가 가장 중요하지 않다면 어떻게 해야 할까요?

경우에 따라 페이지에서 가장 중요한 요소 (또는 요소)가 가장 큰 요소와 동일하지 않을 수 있으며, 개발자는 이러한 다른 요소의 렌더링 시간을 측정하는 데 더 관심이 있을 수 있습니다. 맞춤 측정항목에 관한 도움말에 설명된 대로 Element Timing API를 사용하면 됩니다.

LCP 개선 방법

현장의 LCP 타이밍을 파악하고 실험실 데이터를 사용하여 상세히 살펴보고 최적화하는 프로세스를 알아보려면 LCP 최적화에 관한 전체 가이드를 참조하세요.

추가 리소스

변경 로그

측정항목을 측정하는 데 사용되는 API에서 버그가 발견되기도 하고 측정항목 자체의 정의에서도 버그가 발견되기도 합니다. 그 결과, 때때로 변경이 필요하며, 이러한 변경은 내부 보고서와 대시보드에서 개선 또는 회귀로 표시될 수 있습니다.

이를 관리하는 데 도움이 되도록 이러한 측정항목의 구현 또는 정의에 대한 모든 변경사항이 이 변경 로그에 표시됩니다.

이러한 측정항목에 관한 의견이 있으면 web-vitals-feedback Google 그룹에 제공해 주세요.