레이아웃 변경 디버그

레이아웃 변경을 식별하고 수정하는 방법을 알아봅니다.

Katie Hempenius
Katie Hempenius

이 도움말의 첫 번째 부분에서는 레이아웃 변경 디버깅을 위한 도구에 관해 설명합니다. 두 번째 부분에서는 문제가 발생했을 때 사용할 수 있는 사고 과정에 대해 논의합니다. 레이아웃 변경의 원인을 식별합니다.

도구

레이아웃 불안정성 API

Layout Instability API는 레이아웃 변경을 측정하고 보고하기 위한 브라우저 메커니즘입니다. 모든 도구 DevTools를 포함한 레이아웃 변경 디버깅은 궁극적으로 Layout Instability API 그러나 Layout Instability API를 직접 사용하는 것은 강력한 디버깅 도구입니다.

사용

이전에 생성한 것과 동일한 코드 스니펫레이아웃 변경 횟수 (CLS)가 레이아웃 변경을 디버그하는 데 사용됩니다 아래 스니펫은 레이아웃에 관한 정보를 로깅합니다. 콘솔로 이동합니다 이 로그를 검사하면 레이아웃 변경이 언제, 어디서, 어떻게 발생했는지에 관한 정보를 제공합니다.

let cls = 0;
new PerformanceObserver((entryList) => {
  for (const entry of entryList.getEntries()) {
    if (!entry.hadRecentInput) {
      cls += entry.value;
      console.log('Current CLS value:', cls, entry);
    }
  }
}).observe({type: 'layout-shift', buffered: true});

이 스크립트를 실행할 때는 다음 사항에 유의하세요.

  • buffered: true 옵션은 PerformanceObserver 브라우저의 성능 항목을 확인해 버퍼 이전에 관찰자가 생성한 성능 항목이 초기화하지 않아도 됩니다 따라서 PerformanceObserver는 레이아웃을 보고합니다. 일어난 변화의 비율을 나타냅니다. 보관 명심해야 합니다. 초기 레이아웃 변경은 보고 백로그를 반영할 수 있습니다. 있습니다.
  • 성능에 영향을 주지 않기 위해 PerformanceObserver는 기본 인스턴스가 스레드가 레이아웃 변경을 보고하지 않고 유휴 상태일 수 있습니다. 결과적으로 기본 스레드가 바쁜 상태라면 레이아웃이 실제 스레드와 로그에 기록될 때 발생합니다
  • 이 스크립트는 사용자 입력으로부터 500ms 이내에 발생한 레이아웃 변경을 무시합니다. CLS에 포함되지 않습니다

레이아웃 변경에 관한 정보는 다음 두 API의 조합을 사용하여 보고됩니다. LayoutShiftLayoutShiftAttribution 인터페이스에 추가되었습니다. 이러한 각 인터페이스는 참조하세요

LayoutShift

각 레이아웃 변경은 LayoutShift 인터페이스를 사용하여 보고됩니다. 이 다음과 같이 표시됩니다.

duration: 0
entryType: "layout-shift"
hadRecentInput: false
lastInputTime: 0
name: ""
sources: (3) [LayoutShiftAttribution, LayoutShiftAttribution, LayoutShiftAttribution]
startTime: 11317.934999999125
value: 0.17508567530168798

위의 항목은 세 개의 DOM 요소가 변경되는 동안 레이아웃 변경을 나타냅니다. 있습니다. 이 특정 레이아웃 변경의 레이아웃 변경 점수는 0.175입니다.

다음은 관련성이 가장 높은 LayoutShift 인스턴스의 속성입니다. 레이아웃 변경 디버깅:

속성 설명
sources sources 속성은 레이아웃 변경 중에 이동한 DOM 요소를 나열합니다. 이 배열에는 최대 다섯 개의 소스를 포함할 수 있습니다. 레이아웃 변경의 영향을 받는 요소가 5개 이상인 경우 레이아웃 변경의 가장 큰 요소 5개 (레이아웃 안정성에 대한 영향으로 측정)가 보고됩니다. 이 정보는 LayoutShiftAttribution 인터페이스를 사용하여 보고됩니다 (아래에 더 자세히 설명됨).
value value 속성은 특정 레이아웃 변경의 레이아웃 변경 점수를 보고합니다.
hadRecentInput hadRecentInput 속성은 사용자 입력 후 500밀리초 이내에 레이아웃 변경이 발생했는지 여부를 나타냅니다.
startTime startTime 속성은 레이아웃 변경 시점을 나타냅니다. startTime는 밀리초로 표시되며 페이지 로드가 시작된 시간을 기준으로 측정됩니다.
duration duration 속성은 항상 0로 설정됩니다. 이 속성은 PerformanceEntry 인터페이스에서 상속됩니다 (LayoutShift 인터페이스는 PerformanceEntry 인터페이스를 확장함). 그러나 기간 개념은 레이아웃 변경 이벤트에 적용되지 않으므로 0로 설정됩니다. PerformanceEntry 인터페이스에 관한 자세한 내용은 사양을 참고하세요.

LayoutShiftAttribution

LayoutShiftAttribution 인터페이스는 단일 DOM의 단일 이동을 설명합니다. 요소가 포함됩니다. 레이아웃 변경 중에 여러 요소가 이동하면 sources 속성에 여러 항목이 있습니다.

예를 들어 아래 JSON은 소스가 하나인 레이아웃 변경에 해당합니다. <div id='banner'> DOM 요소를 y: 76에서 아래로 이동 y:246입니다.

// ...
  "sources": [
    {
      "node": "div#banner",
      "previousRect": {
        "x": 311,
        "y": 76,
        "width": 4,
        "height": 18,
        "top": 76,
        "right": 315,
        "bottom": 94,
        "left": 311
      },
      "currentRect": {
        "x": 311,
        "y": 246,
        "width": 4,
        "height": 18,
        "top": 246,
        "right": 315,
        "bottom": 264,
        "left": 311
      }
    }
  ]

node 속성은 이동한 HTML 요소를 식별합니다. 마우스를 가져가면 속성은 해당하는 페이지 요소를 강조표시합니다.

previousRectcurrentRect 속성은 지정할 수도 있습니다

  • xy 좌표는 x 좌표와 y 좌표를 보고합니다. 요소의 왼쪽 상단 모서리와
  • widthheight 속성은 각각 너비와 높이를 보고합니다. 인코더에 전달합니다.
  • top, right, bottom, left 속성은 x 또는 y를 보고합니다. 요소의 지정된 가장자리에 해당하는 좌표 값입니다. 기타 단어의 경우 top 값이 y입니다. bottom의 값은 다음과 같습니다. y+height입니다.

previousRect의 모든 속성이 0으로 설정되면 요소에 볼 수 있습니다. currentRect의 모든 속성이 0으로 설정되면 확인할 수 있습니다.

이러한 출력을 해석할 때 이해해야 할 가장 중요한 것 중 하나는 소스로 나열된 요소는 있습니다. 하지만 이러한 요소는 '근본 원인'과 관련된 설계할 수 있습니다 예를 들면 다음과 같습니다.

예 1

이러한 레이아웃 변경은 하나의 소스인 요소 B로 보고됩니다. 그러나 이 레이아웃 변경의 근본 원인은 요소 A의 크기 변경입니다.

요소 크기 변경으로 인한 레이아웃 변경을 보여주는 예

예 2

이 예에서 레이아웃 변경은 두 소스, 즉 요소 A와 함께 보고됩니다. 볼 수 있습니다. 이 레이아웃 변경의 근본 원인은 요소 A

요소 위치 변경으로 인한 레이아웃 변경을 보여주는 예

예 3

이 예의 레이아웃 변경은 하나의 소스인 요소 B로 보고됩니다. 요소 B의 위치 변경으로 인해 레이아웃이 변경되었습니다.

요소 위치 변경으로 인한 레이아웃 변경을 보여주는 예

예 4

요소 B의 크기는 변경되지만 이 예에서는 레이아웃이 변경되지 않습니다.

요소의 크기는 변경되지만 레이아웃 변경을 유발하지 않는 경우를 보여주는 예

Layout Instability API에서 DOM 변경사항이 보고되는 방식에 관한 데모를 확인하세요.

DevTools

성능 패널

DevTools Performance 패널의 Experience 창에는 특정 성능 트레이스 중에 발생하는 레이아웃 변경 500ms 이내에 발생하므로 CLS에 포함되지 않습니다. 환경 패널에서 특정 레이아웃 변경 위로 마우스를 가져가면 강조표시됩니다. 적용됩니다.

DevTools Network 패널에 표시된 레이아웃 변경의 스크린샷

레이아웃 변경에 관해 자세히 알아보려면 레이아웃 변경을 클릭한 다음 요약 창을 엽니다. 요소의 크기 변경사항이 나열됩니다. [width, height] 형식 사용 요소의 위치 변경사항이 나열됨 [x,y] 형식 사용. 최근 입력 있음 속성은 사용자 상호작용 후 500ms 이내에 레이아웃 변경이 발생했습니다.

DevTools &#39;Summary&#39; 스크린샷 레이아웃 변경 탭

레이아웃 변경 기간에 대한 자세한 내용은 이벤트 로그 탭을 엽니다. 또한 빨간색 레이아웃 변경 직사각형 길이의 Experience

DevTools &#39;Event Log&#39; 스크린샷 레이아웃 변경 탭

성능 패널 사용에 대한 자세한 내용은 성능을 참조하세요. 분석 참조.

레이아웃 변경 영역 강조표시

레이아웃 변경 영역을 강조 표시하면 레이아웃 변경 위치와 타이밍을 한눈에 빠르게 파악할 수 있습니다. 일어날 수 있습니다.

DevTools에서 레이아웃 변경 영역을 사용 설정하려면 설정 > 도구 더보기 > 렌더링 > 레이아웃 변경 영역을 클릭한 다음 디버그할 페이지를 새로고침합니다. 레이아웃 변경 영역이 잠시 보라색으로 강조 표시됩니다.

레이아웃 변경의 원인을 식별하기 위한 사고 프로세스

아래 단계를 사용하여 레이아웃 변경의 원인을 파악할 수 있습니다. 레이아웃 변경 시점이나 방법에 상관이 없습니다 이러한 단계는 Lighthouse는 실행으로 보완됩니다. 하지만 Lighthouse는 초기 페이지 로드 중에 발생한 레이아웃 변경만 식별합니다. 포함 또한 Lighthouse는 레이아웃의 일부 원인에 관한 추천만 제공할 수 있습니다. (예: 너비와 높이가 명시되지 않은 이미지 요소)

레이아웃 변경 원인 식별

레이아웃 변경은 다음과 같은 이벤트로 인해 발생할 수 있습니다.

  • DOM 요소의 위치 변경
  • DOM 요소의 크기 변경사항
  • DOM 요소 삽입 또는 제거
  • 레이아웃을 트리거하는 애니메이션

특히, 변경된 요소 바로 앞에 오는 DOM 요소는 '원인'과 관련될 가능성이 가장 높은 요소 있습니다. 따라서 레이아웃 변경이 발생한 이유를 조사하려면 다음을 고려하세요.

  • 이전 요소의 위치 또는 크기가 변경되었나요?
  • DOM 요소가 이동한 요소보다 먼저 삽입되거나 삭제되었나요?
  • 이동한 요소의 위치가 명시적으로 변경되었나요?

앞의 요소로 인해 레이아웃이 바뀌지 않았다면 다음과 같이 검색을 계속합니다. 다른 선행 요소와 인접한 요소를 고려합니다.

또한 레이아웃 변경의 방향과 거리는 힌트를 제공할 수 있습니다. 살펴봤습니다 예를 들어 하향 변동이 크다는 것은 대개 일반적으로 1픽셀 또는 2픽셀 레이아웃 변경은 충돌하는 CSS 스타일을 적용하거나 웹 글꼴입니다.

<ph type="x-smartling-placeholder">
</ph> 글꼴 전환으로 인한 레이아웃 변경을 보여주는 다이어그램 <ph type="x-smartling-placeholder">
</ph> 이 예에서는 글꼴 교체로 인해 페이지 요소가 위로 5픽셀씩 이동했습니다.

다음은 레이아웃 변경을 가장 자주 유발하는 특정 동작입니다. 이벤트:

요소의 위치 변경 (다른 요소의 이동으로 인한 것이 아닌 경우)

이러한 유형의 변화가 발생하는 이유는 주로 다음과 같습니다.

  • 늦게 로드되거나 이전에 선언된 스타일을 덮어쓰는 스타일시트
  • 애니메이션 및 전환 효과

요소의 크기 변경

이러한 유형의 변화가 발생하는 이유는 주로 다음과 같습니다.

  • 늦게 로드되거나 이전에 선언된 스타일을 덮어쓰는 스타일시트
  • 이후에 로드되는 widthheight 속성이 없는 이미지 및 iframe '슬롯' 알 수 있습니다.
  • width 또는 height 속성이 없는 텍스트 블록은 텍스트가 렌더링됩니다.

DOM 요소 삽입 또는 제거

이러한 현상은 주로 다음과 같은 이유로 발생합니다.

  • 광고 삽입 및 기타 서드 파티 삽입
  • 배너, 알림, 모달 삽입
  • 위에 추가 콘텐츠를 로드하는 무한 스크롤 및 기타 UX 패턴 추가할 수 있습니다.

레이아웃을 트리거하는 애니메이션

일부 애니메이션 효과는 레이아웃을 참조하세요. 일반적인 DOM 요소가 '애니메이션'으로 표시되는 경우입니다. 속성을 증분하여 예를 들어 top 또는 left와 같이 transform 속성 고성능 CSS 애니메이션을 만드는 방법 읽기 를 참조하세요.

레이아웃 변경 재현

재현할 수 없는 레이아웃 변경은 수정할 수 없습니다. 가장 간단하면서도 사이트 레이아웃을 제대로 파악하기 위해 할 수 있는 가장 효과적인 작업 목표 달성을 위해 사이트와 상호작용하는 데 5~10분이 소요됨 레이아웃 변경을 트리거합니다. 이 작업을 수행하는 동안 콘솔을 열어두고 레이아웃 변경을 보고하는 Layout Instability API

레이아웃 변경을 찾기 어려운 경우 연결 속도가 다를 수 있습니다. 특히 더 느린 지연 시간을 레이아웃 변경을 더 쉽게 파악할 수 있습니다. 또한 debugger 문을 사용하여 레이아웃을 더 쉽게 단계별로 실행할 수 있습니다. 있습니다

new PerformanceObserver((entryList) => {
  for (const entry of entryList.getEntries()) {
    if (!entry.hadRecentInput) {
      cls += entry.value;
      debugger;
      console.log('Current CLS value:', cls, entry);
    }
  }
}).observe({type: 'layout-shift', buffered: true});

마지막으로, 개발 시 재현할 수 없는 레이아웃 문제의 경우 다음을 고려하세요. 프런트엔드 로깅 도구와 함께 Layout Instability API 사용 이러한 문제에 대한 추가 정보를 수집할 수 있습니다. 결제 페이지에서 가장 크게 변경된 요소를 추적하는 방법에 대한 예제 코드를 참조하세요.