레이아웃 불안정성 API

커뮤니티 그룹 보고서 초안,

이 버전:
https://wicg.github.io/layout-instability
이슈 추적:
GitHub
명세 내 인라인
편집자:
(Google)
(Google)
(Google)

초록

이 문서는 페이지 내 요소들의 이동을 기반으로 웹 페이지 작성자에게 페이지의 안정성에 대한 통찰을 제공하는 API를 정의한다 .

이 문서의 상태

이 명세는 웹 플랫폼 인큐베이터 커뮤니티 그룹에 의해 게시되었다 . 이는 W3C 표준이 아니며 W3C 표준 트랙에 속하지도 않는다. 다음을 참고하라: W3C 커뮤니티 기여자 라이선스 계약 (CLA) 에 따라 제한된 옵트아웃이 있으며 다른 조건이 적용된다. 다음에서 더 알아보기: W3C 커뮤니티 및 비즈니스 그룹.

1. 소개

이 절은 비규범적입니다.

웹페이지에서 DOM 요소의 이동은 사용자의 경험을 저해하며, 오늘날 웹에서 자주 발생합니다. 이러한 이동은 종종 콘텐츠가 비동기적으로 로드되면서 페이지의 다른 요소들을 밀어내기 때문에 일어납니다.

Layout Instability API는 사용자 세션의 각 애니메이션 프레임마다 (“layout shift”)라는 값을 보고하여 이러한 불안정한 페이지를 식별합니다. 이 명세는 사용자 에이전트가 레이아웃 이동 값을 계산하는 방법을 제안합니다.

레이아웃 이동 값은 특정 시점의 레이아웃 불안정성의 심각도와 대체로 대응됩니다. 이를 산출하는 방법은 불안정성의 영향을 받은 영역의 면적과 페이지 요소가 이동한 거리를 모두 고려합니다.

이 명세에서 노출하는 값들은 여러 이유로 “레이아웃 변경 관측기”로 사용되기 위한 것이 아닙니다. 첫째, 값들이 PerformanceObserver와 연결되므로 사용자 에이전트는 웹사이트 성능에 영향을 주지 않기 위해 콜백 디스패치를 게으르게(lazily) 할 수 있습니다. 둘째, 매우 작은 레이아웃 이동은 사용자 에이전트가 무시할 수 있습니다. 따라서 이 API에 의존하여 웹사이트의 사용자 가시 동작에 영향을 주는 JavaScript를 실행하는 것은 권장되지 않습니다.

1.1. 누적 레이아웃 이동(CLS)

이 절은 비규범적입니다.

레이아웃 이동 값은 단일 시점을 나타내지만, 사용자가 페이지에 머무르는 기간 전체의 불안정성을 나타내는 값을 갖는 것도 유용합니다.

이를 위해 사용자 에이전트 또는 개발자가 이런 값을 계산할 수 있도록 두 가지 값을 제안합니다. (이 정의들은 비규범적이며 API에서 노출되지 않습니다.)

누적 레이아웃 이동 점수는 페이지의 생애 동안의 레이아웃 불안정성 심각도와 대체로 대응됩니다.

개발자는 옵저버에 값이 보고될 때마다 합산하고 visibilitychange 이벤트 시점의 “최종” 값으로 DCLS 또는 CLS 점수를 이 API로 계산할 수 있습니다.

이 전략은 사용 예에서 보여집니다.

1.2. 원인 소스 표시

이 절은 비규범적입니다.

레이아웃 이동 값 외에도, API는 애니메이션 프레임별로 레이아웃 이동에 가장 크게 기여한 최대 5개의 DOM 요소 샘플을 보고합니다. sources 값은 영향 영역 기준 내림차순으로 정렬되어, 첫 번째 요소가 해당 이동에 가장 크게 기여한 요소입니다.

실제 불안정성의 “근본 원인”은 레이아웃 이동이 발생한 DOM 요소와 직접적으로 연결되지 않을 수 있습니다. 예를 들어 새로 삽입된 요소가 그 아래 콘텐츠를 밀어낸 경우, sources 속성은 이동된 요소만을 보고하며 삽입된 요소는 보고하지 않습니다.

우리는 사용자 에이전트가 의미 있는 “근본 원인” 표시를 위해 필요한 수준까지 불안정성의 근거를 파악하는 것은 현실적으로 어렵다고 생각합니다. 그러나 이 API에서 제공되는 더 직접적인 이동 요소 정보도, 레이아웃 불안정성 문제를 진단하는 개발자에게 상당한 도움이 될 것으로 기대합니다.

1.3. 사용 예시

이 절은 비규범적입니다.

let perFrameLayoutShiftData = [];
let cumulativeLayoutShiftScore = 0;

function updateCLS(entries) {
  for (const entry of entries) {
    // Only count layout shifts without recent user input.
    if (entry.hadRecentInput)
      return;

    perFrameLayoutShiftData.push({
      score: entry.value,
      timestamp: entry.startTime
    });
    cumulativeLayoutShiftScore += entry.value;

    // Sources are sorted by impact area in descending order.
    // The first element contributed most to the layout shift.
    if (entry.sources && entry.sources.length > 0) {
      console.log('Largest contributing element:', entry.sources[0].node);
    }
  }
}

// Observe all layout shift occurrences.
const observer = new PerformanceObserver((list) => {
  updateCLS(list.getEntries());
});
observer.observe({type: 'layout-shift', buffered: true});

// Send final data to an analytics back end once the page is hidden.
document.addEventListener('visibilitychange', () => {
  if (document.visibilityState === 'hidden') {
    // Force any pending records to be dispatched.
    updateCLS(observer.takeRecords());

    // Send data to your analytics back end (assumes `sendToAnalytics` is
    // defined elsewhere).
    sendToAnalytics({perFrameLayoutShiftData, cumulativeLayoutShiftScore});
  }
});

레이아웃 이동 점수는 “점프 현상”의 사용자 경험과 대략적으로 상관관계를 갖는 단일 지표일 뿐입니다.

개발자는 레이아웃 이동 점수 간의 작은 변동에 너무 신경 쓰지 않아도 됩니다. 이 측정치는 고정밀 값을 목적으로 하지 않으며, 사용자 에이전트는 계산 효율을 위해 정밀도를 타협할 수 있습니다. 또한, 이 측정치의 정의는 시간이 지남에 따라 변경될 수도 있습니다.

2. 용어

2.1. 기본 개념

시작 지점은 좌표 공간 C에서 Node N에 대해 다음과 같이 정의된다:

변환에 무관한 시작 지점(transform-indifferent starting point)은 좌표 공간 CNode N에 대해, 모든 변형된 요소(transformed element)가 단위 변환 행렬(transformation matrix)을 가진다고 가정한 상태에서 N시작 지점이다.

참고: 노드가 이동했는지 판단하기 위해 변환을 포함한 시작 지점과 변환을 제외한 시작 지점 모두를 고려하는데, 이는 변환(transform) 변화 때문에만 노드가 불안정하다고 판단되지 않도록 보장하기 위함이다. 하지만 CSS transform은 시각적 표현 계산과 뷰포트 외부 포인트의 제외에는 항상 반영된다.

시각적 표현(visual representation)Node N에 대해 다음과 같이 정의된다:

조건이 이전 프레임에서 성립한다는 것은, 레이아웃 이동을 보고(report the layout shift) 알고리즘의 가장 최근 완료 즉시 시점에서 해당 조건이 참임을 의미한다.

Node N의 좌표 공간 C에서의 이전 프레임 시작 지점은, 이전 프레임에서 N시작 지점이었던 점이다.

Node N의 좌표 공간 C에서의 이전 프레임 변환 무관 시작 지점은, 이전 프레임에서 변환에 무관한 시작 지점이었던 점이다.

Node N에 대해 이전 프레임 시각적 표현은, 이전 프레임에서 시각적 표현이었던 점들의 집합이다.

각 사용자 에이전트는 정수형 유의미 픽셀 수(number of pixels to significance)를 정의한다. 이 값은 움직임이 레이아웃 이동으로 간주되는지 판단하는 데 사용된다. 이를 구현별로 허용하여, 사용자 에이전트가 성능이나 사용자 경험에 따라 조정할 수 있다.

AB유의미 픽셀 수 이상, 수평 또는 수직 방향 한쪽에서 픽셀 단위로 차이가 있으면, AB의미있게 다르다(differs significantly)고 한다.

참고: 크롬은 유의미 픽셀 수를 3으로 정의함.

2.2. 불안정한 노드

Node N은 좌표 공간 C에서 이동했다(has shifted)고 한다, 다음의 조건을 모두 만족할 때:

그렇지 않으면 N이동하지 않았다(has not shifted)고 한다.

Node N이 다음 조건을 모두 만족하면 불안정 후보(unstable-candidate)이다:

참고: 스크롤 가능 오버플로우 영역과 관련된 이 조건은 노드가 단순히 스크롤됐다는 이유만으로 불안정하다고 판단되는 것을 방지하기 위한 것이다.

Node N불안정 후보이면서 인라인 클립 교차자(inline clip crosser)가 아니면 불안정(unstable)하다 고 한다.

Node N이 아래 조건을 만족하면 인라인 클립 교차자(inline clip crosser)이다:

참고: 인라인 클립 교차자 예시는, 요소가 인라인 방향으로 클립 경계를 넘어서 보이거나 사라질 때와 같다. 이러한 요소는 block 흐름 방향으로 이동하지 않는 한, 불안정 노드 집합에서 제외된다. 이는 일부 “캐러셀” UI 컨트롤을 쉽게 구현할 수 있도록 돕는다.

Document D불안정 노드 집합(unstable node set)은, D의 모든 불안정(unstable) shadow-including descendant를 포함하는 집합이다.

참고: 첫 프레임에서는 노드마다 이전 프레임 시작 지점이 존재하지 않으므로, 이 시점의 불안정 노드 집합은 비어있다.

2.3. 레이아웃 이동 값

뷰포트 기준 거리시각적 뷰포트 너비시각적 뷰포트 높이 중 큰 값이다.

이동 벡터(move vector)Node N에 대해 픽셀 단위의 2차원 오프셋으로 정의된다:

이동 거리(move distance)Node N에 대해 다음 두 값 중 큰 값이다.

최대 이동 거리(maximum move distance)Document D불안정 노드 집합 내 각 Node이동 거리 중 가장 큰 값이다. 만약 불안정 노드 집합이 비어 있으면 0이다.

거리 비율(distance fraction)Document D에 대해 다음 두 값 중 작은 값이다.

노드 영향 영역(node impact region)불안정 Node N에 대해 다음 두 집합의 합집합이다:

영향 영역(impact region)Document D불안정 노드 집합 내 각 Node노드 영향 영역 전체 점의 집합이다.

영향 비율(impact fraction)Document D영향 영역의 면적을 뷰포트의 면적으로 나눈 값이다. (뷰포트의 면적이 0이면 0)

참고: 영향 영역의 면적 계산은 2차원 Klee 측정 문제의 한 예시다. sweep line 및 세그먼트 트리를 사용하는 시간복잡도 O(n lg n) 알고리즘 예시는 여기에 설명되어 있다.

레이아웃 이동 값(layout shift value)Document D에 대해 영향 비율거리 비율을 곱한 값이다.

참고: 레이아웃 이동 값은 레이아웃 불안정성이 뷰포트에서 차지하는 면적 비율과, 실제로 움직인 최대 거리 모두를 고려한다. 크기가 큰 요소가 소폭 이동해도 페이지의 불안정성 체감에는 미치는 영향이 작을 수 있음을 반영한다.

2.4. 입력 배제

배제 입력(excluding input)은 입력 장치에서 발생한 사용자의 문서와의 적극적 상호작용을 알리는 이벤트이거나, 뷰포트 크기를 직접 변경하는 이벤트이다.

배제 입력에는 보통 mousedown, keydown, pointerdownchange 이벤트가 포함된다. 단, flick 또는 스크롤 제스처를 시작하거나 갱신하는 것만이 효과인 이벤트는 배제 입력이 아니다.

사용자 에이전트는 pointerdown 이벤트 이후, 해당 이벤트가 flick 또는 스크롤 제스처의 시작이 아님을 알 때까지 레이아웃 이동 보고를 지연할 수 있다.

mousemovepointermove 이벤트도 배제 입력에 해당하지 않는다.

3. LayoutShift 인터페이스

[Exposed=Window]
interface LayoutShift : PerformanceEntry {
  readonly attribute double value;
  readonly attribute boolean hadRecentInput;
  readonly attribute DOMHighResTimeStamp lastInputTime;
  readonly attribute FrozenArray<LayoutShiftAttribution> sources;
  [Default] object toJSON();
};

모든 속성은 레이아웃 이동을 보고 단계에서 할당된 값을 가진다.

sources 속성은 FrozenArray 타입의 LayoutShiftAttribution 객체 배열을 반환한다. 영향 영역 크기 기준 내림차순 정렬되며, 첫 번째 요소가 노드 영향 영역이 가장 크고 레이아웃 이동에 가장 크게 기여한 요소를 의미한다.

Layout Instability API를 구현하는 사용자 에이전트는 Window 컨텍스트의 supportedEntryTypes"layout-shift"를 반드시 포함해야 한다. 이를 통해 개발자는 Layout Instability API 지원 여부를 감지할 수 있다.

4. LayoutShiftAttribution 인터페이스

[Exposed=Window]
interface LayoutShiftAttribution {
  readonly attribute Node? node;
  readonly attribute DOMRectReadOnly previousRect;
  readonly attribute DOMRectReadOnly currentRect;
};

참고: previousRectcurrentRect 속성은 CSS 픽셀 단위로 보고된다. 이는 getBoundingClientRect(), IntersectionObserver, ResizeObserver 등 다른 Web Platform API와 일치한다. 이로 인해 레이아웃 이동 측정과 다른 DOM 측정의 좌표 일관성을 보다 쉽게 확보할 수 있다.

LayoutShiftAttributionNode (이를 관련 노드(associated node)라 한다)와 연관되어 있다.

LayoutShiftAttribution 인스턴스 Anode 속성 getter는, Aget an element 알고리즘을 A관련 노드 및 해당 node document를 인수로 하여 호출한 결과를 반환한다.

참고: get an element 알고리즘을 사용함으로써, node 속성은 관련 노드가 더 이상 연결되어 있지 않거나 shadow root 내부에 있을 경우 null이 된다.

get an element 알고리즘은 Element Timing 명세에서 분리되어 이 명세에서도 재사용 가능해야 함.

get an element 알고리즘은 Node 타입을 수용하도록 일반화되어야 하며 Element 타입에 한정되지 않아야 한다.

previousRectcurrentRect 속성은 귀속 생성(create the attribution) 단계에서 할당된 값을 가진다.

5. 처리 모델

렌더링 갱신(update the rendering) 단계 내에서, 이벤트 루프 처리 모델(event loop processing model)의 일부로, Layout Instability API를 구현하는 사용자 에이전트는 페인트 타이밍 기록(mark paint timing) 단계 이후 다음 단계를 반드시 수행해야 한다:

  1. 모든 fully active Document docs에 대해, 해당 Document레이아웃 이동을 보고 알고리즘을 호출한다.

5.1. 레이아웃 이동 보고

active Document D에 대해 레이아웃 이동을 보고(report the layout shift)할 때, 다음 절차를 수행한다:
  1. 현재 D레이아웃 이동 값이 0이 아니라면:

    1. D관련 realm에서, LayoutShift 객체 newEntry를 새로 생성한다.

    2. newEntryname 속성에 "layout-shift"를 할당한다.

    3. newEntryentryType 속성에 "layout-shift"를 할당한다.

    4. newEntrystartTime 속성에 현재 고해상도 시간(current high resolution time)D관련 전역 객체(relevant global object) 기준으로 할당한다.

    5. newEntryduration 속성에 0을 할당한다.

    6. newEntryvalue 속성에 현재 D레이아웃 이동 값을 할당한다.

    7. newEntrylastInputTime 속성에 가장 최근 배제 입력의 시각을 할당한다. 세션 중 배제 입력이 일어나지 않았다면 0으로 한다.

    8. newEntryhadRecentInput 속성에 true를 할당(단, lastInputTime 이 직전 500ms 미만이면), 아니면 false를 할당.

    9. newEntrysources 속성에 D에 대한 레이아웃 이동 소스 보고(report the layout shift sources) 알고리즘 호출 결과를 할당.

    10. PerformanceEntry 큐(queue a PerformanceEntry) newEntry 객체.

5.2. 레이아웃 이동 소스 보고

active Document D에 대해 레이아웃 이동 소스 보고(report the layout shift sources)를 요청받으면, 다음 단계를 수행한다:
  1. CNode 객체들의 빈 리스트로 둔다.

  2. D불안정 노드 집합의 각 멤버 N마다 아래를 수행한다:

    1. 만약 C의 어떤 멤버 existingNode가 존재하여 N노드 영향 영역existingNode노드 영향 영역의 부분집합이라면, 다음 단계로 넘어간다.

    2. 그렇지 않고, C의 멤버 existingNodeexistingNode노드 영향 영역N노드 영향 영역의 부분집합이면, replace(교체)를 통해 해당 existingNodeC에서 N으로 바꾼다.

    3. 그것도 아니라면, C의 멤버가 5개 미만이면 append(추가)로 NC에 넣는다.

      참고: 5개라는 값은 임의이지만, 메모리 제한과 노드 셋 과다 노출 방지 사이에서 상세 귀속 정보를 제공하는 타협값이다.

    4. 그 외의 경우, 아래 단계를 실행한다:

      1. C 멤버 중 노드 영향 영역의 면적이 어떤 다른 멤버보다 작지 않은 첫 멤버를 smallest라 한다.

      2. N노드 영향 영역 면적이 smallest노드 영향 영역 면적보다 크다면 replaceC에서 smallestN으로 교체한다.

  3. 내림차순 정렬C를 정렬한다. 노드 영향 영역 면적이 작은 것이 큰 것보다 앞에 오도록 한다.

    참고: 이를 통해 sources 속성이 영향 영역 내림차순으로, 레이아웃 이동에 가장 크게 기여한 요소가 가장 먼저 노출되도록 보장한다.

  4. C 각 멤버에 대해 귀속 생성(create the attribution) 알고리즘을 실행해 만들어진 FrozenArray 타입의 LayoutShiftAttribution 객체 배열을 반환한다.

Node N에 대해 귀속 생성(create the attribution)을 요청받으면 아래 단계를 수행한다:
  1. N관련 realm에서 LayoutShiftAttribution 객체 A를 생성한다.

  2. A관련 노드N으로 설정한다.

  3. N이전 프레임 시각적 표현을 포함하는 최소의 사각형(Rectangle)(단위: CSS 픽셀)을 previousRect 속성에 설정한다.

  4. N시각적 표현을 포함하는 최소의 사각형(Rectangle)(단위: CSS 픽셀)을 currentRect 속성에 설정한다.

  5. A를 반환한다.

6. 보안 및 개인정보 보호 고려사항

레이아웃 불안정성(layout instability)은 resource timing과 간접적으로 관련이 있다. 느린 리소스는 그렇지 않았을 중간 레이아웃을 유발할 수 있다. Resource timing 정보는 악의적인 사이트가 통계적 핑거프린팅(statistical fingerprinting)에 악용할 수 있다. 레이아웃 불안정성 API는 현재 브라우징 컨텍스트에 대해서만 불안정성을 보고한다. 여러 브라우징 컨텍스트의 점수를 직접 합산하지 않는다. 개발자가 직접 합산 코드를 구현할 수는 있으나, origin이 다른 브라우징 컨텍스트들에서는 협력 없이는 점수 공유가 불가능하다.

적합성

문서 관례

적합성 요구사항은 설명적 단언과 RFC 2119 용어를 조합하여 표현한다. 이 문서의 규범적 부분에서 “MUST”, “MUST NOT”, “REQUIRED”, “SHALL”, “SHALL NOT”, “SHOULD”, “SHOULD NOT”, “RECOMMENDED”, “MAY”, “OPTIONAL” 등의 주요 단어는 RFC 2119에서 정의된 대로 해석해야 한다. 하지만 가독성을 위해 본 명세에서는 이 단어들을 모두 대문자로 표기하지 않는다.

이 명세의 모든 본문 텍스트는 규범적이며, 명시적으로 비규범적임을 표시한 절, 예시, 주석만 예외이다. [RFC2119]

본 명세의 예시는 “예를 들어”로 시작하거나, 또는 다음과 같이 class="example" 클래스와 함께 본문에서 구분된다:

이것은 안내용 예시의 한 예입니다.

비규범적 주석(Informative note)은 “참고”라는 단어로 시작하며, 다음과 같이 class="note" 클래스로 본문과 구분된다:

참고, 이것은 안내용 주석입니다.

색인

이 명세에서 정의된 용어

참조로 정의된 용어

참고문헌

규범적 참고문헌

[CSS-BREAK-4]
Rossen Atanassov; Elika Etemad. CSS Fragmentation Module Level 4. URL: https://drafts.csswg.org/css-break-4/
[CSS-CASCADE-5]
Elika Etemad; Miriam Suzanne; Tab Atkins Jr.. CSS Cascading and Inheritance Level 5. URL: https://drafts.csswg.org/css-cascade-5/
[CSS-COLOR-3]
Tantek Çelik; Chris Lilley; David Baron. CSS Color Module Level 3. URL: https://drafts.csswg.org/css-color-3/
[CSS-DISPLAY-4]
Elika Etemad; Tab Atkins Jr.. CSS Display Module Level 4. URL: https://drafts.csswg.org/css-display-4/
[CSS-OVERFLOW-3]
Elika Etemad; Florian Rivoal. CSS Overflow Module Level 3. URL: https://drafts.csswg.org/css-overflow-3/
[CSS-TEXT-3]
Elika Etemad; Koji Ishii; Florian Rivoal. CSS Text Module Level 3. URL: https://drafts.csswg.org/css-text-3/
[CSS-TRANSFORMS-1]
Simon Fraser; et al. CSS Transforms Module Level 1. URL: https://drafts.csswg.org/css-transforms/
[CSS-VALUES-4]
Tab Atkins Jr.; Elika Etemad. CSS Values and Units Module Level 4. URL: https://drafts.csswg.org/css-values-4/
[CSS-WRITING-MODES-4]
Elika Etemad; Koji Ishii. CSS Writing Modes Level 4. URL: https://drafts.csswg.org/css-writing-modes-4/
[CSS2]
Bert Bos; et al. Cascading Style Sheets Level 2 Revision 1 (CSS 2.1) Specification. URL: https://drafts.csswg.org/css2/
[CSSOM-VIEW-1]
Simon Fraser; Emilio Cobos Álvarez. CSSOM View Module. URL: https://drafts.csswg.org/cssom-view/
[DOM]
Anne van Kesteren. DOM Standard. Living Standard. URL: https://dom.spec.whatwg.org/
[ELEMENT-TIMING]
Element Timing API. Editor's Draft. URL: https://w3c.github.io/element-timing/
[GEOMETRY-1]
Simon Pieters; Chris Harrelson. Geometry Interfaces Module Level 1. URL: https://drafts.fxtf.org/geometry/
[HR-TIME-2]
Ilya Grigorik. High Resolution Time Level 2. URL: https://w3c.github.io/hr-time/
[HTML]
Anne van Kesteren; et al. HTML Standard. Living Standard. URL: https://html.spec.whatwg.org/multipage/
[PAINT-TIMING]
Ian Clelland; Noam Rosenthal. Paint Timing. URL: https://w3c.github.io/paint-timing/
[PERFORMANCE-TIMELINE]
Nicolas Pena Moreno. Performance Timeline. URL: https://w3c.github.io/performance-timeline/
[RESOURCE-TIMING]
Yoav Weiss; Noam Rosenthal. Resource Timing. URL: https://w3c.github.io/resource-timing/
[RFC2119]
S. Bradner. Key words for use in RFCs to Indicate Requirement Levels. March 1997. Best Current Practice. URL: https://datatracker.ietf.org/doc/html/rfc2119
[VISUAL-VIEWPORT]
Visual Viewport API. cg-draft. URL: https://wicg.github.io/visual-viewport/
[WEBIDL]
Edgar Chen; Timothy Gu. Web IDL Standard. Living Standard. URL: https://webidl.spec.whatwg.org/

정보성 참고문헌

[INTERSECTION-OBSERVER]
Stefan Zager; Emilio Cobos Álvarez; Traian Captan. Intersection Observer. URL: https://w3c.github.io/IntersectionObserver/
[RESIZE-OBSERVER-1]
Aleks Totic; Greg Whitworth. Resize Observer. URL: https://drafts.csswg.org/resize-observer/

IDL 색인

[Exposed=Window]
interface LayoutShift : PerformanceEntry {
  readonly attribute double value;
  readonly attribute boolean hadRecentInput;
  readonly attribute DOMHighResTimeStamp lastInputTime;
  readonly attribute FrozenArray<LayoutShiftAttribution> sources;
  [Default] object toJSON();
};

[Exposed=Window]
interface LayoutShiftAttribution {
  readonly attribute Node? node;
  readonly attribute DOMRectReadOnly previousRect;
  readonly attribute DOMRectReadOnly currentRect;
};

이슈 색인

get an element 알고리즘은 Element Timing 명세에서 분리되어 이 명세에서 재사용될 수 있는 위치로 옮겨야 한다.
get an element 알고리즘은 NodeElement 대신 받을 수 있도록 범용적으로 변경되어야 한다.