Largest Contentful Paint

ave10987·2022년 12월 22일
0

LCP란?

  • google에서 제시한 core web vitals 지표 중 하나
  • 페이지가 처음 로드를 시작한 시점을 기준으로 뷰포트 내에 있는 가장 큰 이미지 또는 텍스트 블록의 렌더링 시간

google에서 제안하는 좋은 LCP score

  • 우수한 사용자 경험을 위해서 전체 LCP의 75번째 백분위 수(percentile)가 2.5초 이하가 되는 것을 권장

LCP로 측정되는 요소들

  • <img> element
  • <svg> 내부의 <image>
  • <video> element (포스터 이미지가 사용된 경우)
  • url() 을 통해 로드된 배경 이미지가 있는 element
  • 텍스트 노드 또는 텍스트를 포함한 block element
  • canvas 요소는 LCP로 측정되지 않음
  • 아래 화면은 공룡이 노출되는 canvas영역(빨간색 박스) 대신 textnode가 LCP로 측정된 예시

LCP가 측정되는 시점

  • 브라우저가 화면을 그리면서 단계적으로 LCP 후보군을 찾음
  • 발견된 모든 콘텐츠를 분석해 가장 큰 내용이 새로 발견되면 LCP 후보군을 변경
  • 아래 예시 화면 처럼 랜더링 시점에 따라 LCP로 선택된 요소가 변경됨
  • 주의 사항
    1. LCP 후보군으로 선택된 element의 크기나 위치가 변경되어도 새로운 LCP 후보군으로 변경되지 않음
      • 즉, viewport 밖에서 렌더링된 후 viewport 안으로 이동된 요소는 LCP로 선택되지 않음
      • 반대로 viewport안에서 렌더링된 후 viewport 밖으로 이동된 요소가 LCP로 선택될 수도 있음
    2. 화면이 전부 렌더링되기 전까지 LCP는 변경될 수 있음
      • 만약 위 예시 화면에서 두번째 frame에 LCP를 측정하면 화면 상단 textnode가 LCP로 측정됨
      • 모든 화면이 렌더링된 후에는 img tag가 LCP로 측정됨

LCP 측정 방법

  • 실험실 도구를 사용
  • 직접 측정 방법
    • JavaScript를 이용
          new PerformanceObserver((entryList) => {
                for (const entry of entryList.getEntries()) {
                  console.log('LCP candidate:', entry.startTime, entry);
                }
            }).observe({type: 'largest-contentful-paint', buffered: true});
    • web-vitals library를 이용
      • 자신의 환경에 맞는 js를 build options을 확인하여 사용

LCP 지표 수집

  • Lab 환경이 아닌 RUM(Real User Monitoring) 데이터를 수집하고자 하는 경우
  • LCP 측정 방법직접 측정 방법 중 한가지를 이용해 사용자 LCP를 측정하고 측정된 데이터를 수집
  • LCP 지표를 수집하는 시점에 대한 고민이 필요
    • LCP가 측정되는 시점의 내용에 따라 LCP는 화면이 렌더링되면서 변경될 수 있음
    • 그렇다면 언제 LCP지표를 수집해야 정확한 LCP 지표를 확인할 수 있을것인가?
      1. LCP 후보군이 변경될 때 마다 로그를 전송
        • 장점
          • 정확한 LCP 지표 측정 가능
        • 단점
          • 전송된 로그 중 마지막 LCP 지표를 구분할 수 있어야 함 (eg. 한 페이지에서 다섯번의 LCP 후보군이 변경되었고 변경 시점마다 로그가 전송된다면 마지막 로그를 어떻게 구분할 것인지)
          • LCP 후보군 변경에 따른 로그 전송량이 많아질 수 있음
      2. 페이지 이탈 시점에 로그를 전송
        • 장점
          • LCP 후보군을 따로 추적하지 않아도 되며 로그 전송 비용을 줄일 수 있음
        • 단점
          • 측정하고자 하는 LCP 요소가 화면에 렌더링되기 전에 사용자가 페이지를 이탈하게 되면 잘못된 LCP 요소가 측정될 수 있음
        • 참고
          • 페이지 이탈 시점에 로그를 전송하는 것은 Beacon API사용을 권장 (일반 API 요청은 페이지 이탈 시 반드시 전송된다고 보장할 수 없음)

수집한 LCP 지표의 noise 제거

  • 다음의 경우에 LCP는 측정 의도와 다른 값이 수집될 수 있음 (Noise Canceling RUM 참고)
    1. navigation type 0이 아닌 상태에서 측정된 LCP
      • navigation type은 navigate, reload, back_forward, prerender 중 한가지
      • navigate 값은 사용자가 링크를 클릭하거나 URL을 입력해서 진입하는 경우
      • navigate값이 전달되는 경우를 제외하면 cache등의 영향으로 기대한 것과 다른 LCP 지표가 측정될 수 있음 (매우 빠를 확률이 높음)
    2. visibility hidden 상태에서 측정된 LCP
      • visibility state에 따라 웹페이지 로딩 성능이 달라짐
      • visibility hidden인 상태에서 측정된 LCP 75th 수치는 visible 상태에서 측정된 수치보다 약 23% 느림 (Page Visibility: If a tree falls in the forest 참고)

LCP의 구성

  • LCP = TTFB(Time To First Byte) + LCP(FE rendering time) (LCP[FE]참고)
  • LCP = TTFB + LCP(Resource Load Delay + Resource Load Time + Element Render Delay)
  • LCP가 2.5s 안으로 들어오기 위해 LCP를 구성하는 각 영역을 아래와 같은 목표로 설정 (A deep dive into optimizing LCP 참고)
    • 위와 같이 설정할 수 있는 근거
      • HTTP Archive의 public data를 바탕으로 확인해보니 LCP 구간 별 각 영역이 차지하는 시간이 아래와 같음
      • 위 그래프를 전체 LCP중 각 영역이 차지하는 비율로 계산하면 아래와 같음
      • 의외로 resource load time(주로 image일 것으로 예상) 보다 resource load delay가 많은 영향을 주는 것을 확인할 수 있음

LCP 개선 방법

  • 서버 응답 시간 개선
  • 렌더링 차단 JavaScript 및 CSS 제거
  • 리소스 로드 시간 단축
  • 클라이언트 렌더링 개선

참고 자료

0개의 댓글