카테고리 없음

[모리딥] 누적 레이아웃 이동(CLS)

Ahyeon, Jung 2024. 3. 25. 17:49

누적 레이아웃 이동(Cumulative Layout Shift, CLS)

 

웹 페이지의 시각적 안정성을 측정하는 지표 중 하나페이지의 생명주기 동안 발생하는 모든 예기치 않은 이동에 대한 지표를 계산하며 사용자가 예상치 못한 레이아웃 이동을 경험하는 빈도를 수량화한다. 사용자가 페이지를 로드하는 동안 렌더링되는 요소들의 위치 변화로 인해 발생하는 사용자 경험의 불안정성을 나타내므로 CLS가 낮으면 사용자 경험을 악화시킨다.

 

리소스가 비동기식으로 로드되거나, DOM 요소가 기존 콘텐츠 위의 페이지에 동적으로 추가 되어 발생한다. 사용자의 인터렉션으로 인한 레이아웃 변경인 경우는 포함되지 않으며, 레이아웃 이동이 발생한 요소의 전체 높이와 뷰포트 높이의 비율을 의미하는 영향분율과 레이아웃 이동이 발생한 요소가 뷰포트 대비 얼마나 이동했는지를 의미하는 거리분율을 곱해 최종 점수를 계산한다.

측정 방법

Layout Instability API 사용

  1. PerformanceObserver 객체를 생성하여 레이아웃 안전성을 관찰
  2. Observer 시작
  3. PerformanceObserver 콜백함수 내에서 관찰된 이벤트들을 처리
  4. 페이지 언로드 시 Observer 종료
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Layout Shift Example</title>
    <style>
      .container {
        width: 200px;
        height: 200px;
        border: 1px solid black;
        overflow: hidden;
        position: relative;
      }

      .moving-element {
        width: 100px;
        height: 100px;
        background-color: red;
        position: absolute;
        top: 0;
        left: 0;
        animation: move 5s infinite;
      }

      @keyframes move {
        0% {
          top: 0;
          left: 0;
        }
        50% {
          top: 100px;
          left: 100px;
        }
        100% {
          top: 0;
          left: 0;
        }
      }
    </style>
  </head>
  <body>
    <div class="container">
      <div class="moving-element"></div>
    </div>

    <script>
      // DOM이 로드되면 PerformanceObserver 객체를 생성
      window.addEventListener("DOMContentLoaded", () => {
        const observer = new PerformanceObserver((list) => {
          const entries = list.getEntries();
          entries.forEach((entry) => {
            // layout-shift 이벤트를 감지하고 콘솔에 출력
            if (entry.entryType === "layout-shift" && entry.value > 0) {
              console.log("Layout Shift Score:", entry.value);
            }
          });
        });

        observer.observe({ type: "layout-shift", buffered: true });

        window.addEventListener("unload", () => {
          observer.disconnect();
        });
      });
    </script>
  </body>
</html>

 

web-vitals 라이브러리

// DOMContentLoaded 이벤트가 발생하면 CLS를 측정
document.addEventListener('DOMContentLoaded', () => {
  // getCLS 함수를 호출하여 CLS를 측정하고 결과를 콘솔에 출력
  window.webVitals.getCLS(console.log);
});
  • DOMContentLoaded: HTML 문서의 파싱이 완료되고, DOM 트리가 생성된 후 발생하는 이벤트
  • onload: 웹 페이지의 모든 리소스(HTML, CSS, 이미지, 스크립트 등)가 로드도니 후에 발생하는 이벤트

개선 방안

삽입이 예상되는 요소를 위한 추가적인 공간 확보폰트 로딩 최적화적절한 이미지 크기 설정

 

Reference

모던 리액트 딥다이브

[웹 성능] 책에서 읽은 웹 성능에 관한 내용 : 네이버 블로그 (naver.com)

Layout Instability API (wicg.github.io)


CLS가 좋지 않았던 페이지의 불편함을 알다보니 이해는 가지만, CLS 점수가 의미하는게 뭔지는 잘 모르겠다.