긴 애니메이션 프레임 API

Long Animation Frames API (LoAF로 발음하는 Lo-Af)는 느린 사용자 인터페이스 (UI) 업데이트를 더 잘 이해할 수 있도록 Long Tasks API의 업데이트입니다. 이는 응답성을 측정하는 다음 페인트 (INP)에 대한 상호작용 Core Web Vitals 측정항목에 영향을 줄 수 있는 느린 애니메이션 프레임을 식별하거나 부드러움에 영향을 미치는 다른 UI 버벅거림을 식별하는 데 유용할 수 있습니다.

API의 상태

브라우저 지원

  • Chrome: 123 <ph type="x-smartling-placeholder">
  • Edge: 123. <ph type="x-smartling-placeholder">
  • Firefox: 지원되지 않음 <ph type="x-smartling-placeholder">
  • Safari: 지원되지 않음 <ph type="x-smartling-placeholder">

소스

Chrome 116에서 Chrome 122로의 오리진 트라이얼에 이어 LoAF API가 Chrome 123에서 출시되었습니다.

배경: Long Tasks API

브라우저 지원

  • Chrome: 58. <ph type="x-smartling-placeholder">
  • Edge: 79. <ph type="x-smartling-placeholder">
  • Firefox: 지원되지 않음 <ph type="x-smartling-placeholder">
  • Safari: 지원되지 않음 <ph type="x-smartling-placeholder">

소스

Long Animation Frames API는 Chrome 58 이후로 한동안 Chrome에서 사용할 수 있었던 Long Tasks API의 대안입니다. 이름에서 알 수 있듯이 Long Task API를 사용하면 기본 스레드를 50밀리초 이상 점유하는 긴 작업을 모니터링할 수 있습니다. PerformanceLongTaskTiming 인터페이스와 PeformanceObserver를 사용하여 긴 작업을 모니터링할 수 있습니다.

const observer = new PerformanceObserver((list) => {
  console.log(list.getEntries());
});

observer.observe({ type: 'longtask', buffered: true });

장기 작업은 응답 문제를 일으킬 수 있습니다. 사용자가 버튼을 클릭하거나 메뉴를 여는 등 페이지와 상호작용하려고 하지만 기본 스레드에서 이미 긴 작업을 처리하고 있다면 작업이 완료되기를 기다리는 동안 사용자의 상호작용이 지연됩니다.

응답성을 개선하려면 장기 작업을 분할하는 것이 좋습니다. 각각의 긴 작업을 일련의 더 작은 여러 작업으로 나누는 경우, 상호작용 응답의 현저한 지연을 피하기 위해 작업들 사이에 더 중요한 작업을 실행할 수 있습니다.

따라서 응답성을 개선하기 위해 가장 먼저 해야 할 일은 성능 트레이스를 실행하고 장기 작업을 살펴보는 것입니다. Lighthouse (긴 기본 스레드 작업 피하기 감사가 있음)와 같은 실험실 기반 감사 도구를 사용하거나 Chrome DevTools에서 장기 작업을 확인할 수 있습니다.

실험실 기반 테스트는 반응성 문제를 식별하는 데 좋은 시작점이 될 수 없는 경우가 많습니다. 이러한 도구에는 상호작용이 포함되지 않을 수 있기 때문입니다. 이러한 도구는 가능한 상호작용의 작은 하위 집합입니다. 현장에서 느린 상호작용이 발생하는 원인을 측정하는 것이 이상적입니다.

Long Tasks API의 단점

Performance Observer를 사용하여 현장에서 장기 작업을 측정하는 것은 다소 유용합니다. 그러나 실제로는 긴 작업이 발생했다는 사실과 소요된 시간 외에 많은 정보를 제공하지 않습니다.

실제 사용자 모니터링 (RUM) 도구는 보통 이를 사용하여 장기 작업의 수나 기간을 추세하거나 어떤 페이지에서 작업이 발생하는지 파악합니다. 그러나 장기 작업의 원인에 대한 기본적인 세부 정보 없이는 이 기능의 활용 범위가 제한적입니다. Long Tasks API에는 기본 기여 분석 모델만 있습니다. 이 모델은 장기 작업이 발생한 컨테이너 (최상위 문서 또는 <iframe>)만 알려주고 일반 항목에서 볼 수 있듯이 이를 호출한 스크립트나 함수는 알려주지 않습니다.

{
  "name": "unknown",
  "entryType": "longtask",
  "startTime": 31.799999997019768,
  "duration": 136,
  "attribution": [
    {
      "name": "unknown",
      "entryType": "taskattribution",
      "startTime": 0,
      "duration": 0,
      "containerType": "window",
      "containerSrc": "",
      "containerId": "",
      "containerName": ""
    }
  ]
}

또한 Long Tasks API는 일부 중요한 작업을 제외할 수 있으므로 불완전한 뷰입니다. 렌더링과 같은 일부 업데이트는 개별 작업에서 발생합니다. 이러한 업데이트는 해당 업데이트가 '총 작업'을 정확하게 측정하도록 한 이전 실행과 함께 포함되는 것이 이상적입니다. 확인할 수 있습니다. 작업 사용 시 제한사항에 대한 자세한 내용은 '장기 작업이 부족한 경우' 섹션을 참조하세요.

마지막 문제는 긴 작업을 측정하면 50밀리초 제한을 초과하는 개별 작업만 보고된다는 점입니다. 애니메이션 프레임은 이 50밀리초 제한보다 작은 여러 작업으로 구성될 수 있지만 여전히 브라우저의 렌더링 기능을 전체적으로 차단합니다.

Long Animation Frames API

브라우저 지원

  • Chrome: 123 <ph type="x-smartling-placeholder">
  • Edge: 123. <ph type="x-smartling-placeholder">
  • Firefox: 지원되지 않음 <ph type="x-smartling-placeholder">
  • Safari: 지원되지 않음 <ph type="x-smartling-placeholder">

소스

Long Animation Frames API (LoAF)는 새로운 API로, Long Tasks API의 몇 가지 단점을 해결하여 개발자가 응답성 문제를 해결하고 INP를 개선하는 데 도움이 되는 활용 가능한 분석 정보를 더 많이 얻을 수 있도록 지원합니다.

반응성이 좋다는 것은 페이지에서 발생하는 상호작용에 빠르게 반응한다는 뜻입니다. 여기에는 사용자가 필요로 하는 모든 업데이트를 적시에 페인트할 수 있어야 하고 이러한 업데이트가 발생하지 않도록 차단되지 않아야 합니다. INP의 경우 200밀리초 이하로 응답하는 것이 좋지만 다른 업데이트 (예: 애니메이션)의 경우에는 너무 길더라도 응답하는 것이 좋습니다.

Long Animation Frames API는 차단 작업을 측정하는 또 다른 접근 방식입니다. Long Animation Frames API는 이름에서 알 수 있듯이 개별 작업을 측정하는 대신 긴 애니메이션 프레임을 측정합니다. 긴 애니메이션 프레임은 렌더링 업데이트가 50밀리초 (Long Tasks API의 기준점과 동일함) 이상 지연되는 경우입니다.

긴 애니메이션 프레임은 PerformanceObserver가 있는 긴 작업과 비슷한 방식으로 관찰할 수 있지만 대신 long-animation-frame 유형을 확인합니다.

const observer = new PerformanceObserver((list) => {
  console.log(list.getEntries());
});

observer.observe({ type: 'long-animation-frame', buffered: true });

이전의 긴 애니메이션 프레임도 다음과 같이 성능 타임라인에서 쿼리할 수 있습니다.

const loafs = performance.getEntriesByType('long-animation-frame');

그러나 성능 항목의 maxBufferSize가 있으며 이후 최신 항목이 삭제되므로 PerformanceObserver 접근 방식을 사용하는 것이 좋습니다. long-animation-frame 버퍼 크기는 long-tasks와 마찬가지로 200으로 설정됩니다.

작업 대신 프레임을 볼 때의 이점

작업의 관점이 아니라 프레임 관점에서 보면, 긴 애니메이션은 누적되어 긴 애니메이션 프레임이 되는 수많은 작업으로 구성될 수 있다는 것입니다. 이는 애니메이션 프레임 전의 렌더링 차단 작업이 많은 작은 작업의 합계가 Long Tasks API에 의해 표시되지 않을 수 있다는 마지막 문제를 해결합니다.

긴 작업에서 이 대체 뷰의 추가적인 이점은 전체 프레임의 타이밍 분석을 제공할 수 있다는 것입니다. LoAF에는 Long Tasks API와 같이 startTimeduration만 포함하는 대신 다음과 같은 프레임 지속 시간의 다양한 부분에 관한 훨씬 더 자세한 분석이 포함되어 있습니다.

  • startTime: 탐색 시작 시간을 기준으로 한 긴 애니메이션 프레임의 시작 시간입니다.
  • duration: 긴 애니메이션 프레임의 지속 시간입니다 (표시 시간 제외).
  • renderStart: 렌더링 주기의 시작 시간으로, requestAnimationFrame 콜백, 스타일 및 레이아웃 계산, 크기 조절 관찰자 및 교차 관찰자 콜백이 포함됩니다.
  • styleAndLayoutStart: 스타일 및 레이아웃 계산에 사용된 기간의 시작입니다.
  • firstUIEventTimestamp: 이 프레임이 진행되는 동안 처리될 첫 번째 UI 이벤트 (마우스/키보드 등)의 시간입니다.
  • blockingDuration: 애니메이션 프레임이 차단되고 있던 시간(밀리초)입니다.

이러한 타임스탬프를 사용하면 긴 애니메이션 프레임을 타이밍으로 나눌 수 있습니다.

타이밍 계산
시작 시간 startTime
종료 시간 startTime + duration
작업 기간 renderStart ? renderStart - startTime : duration
렌더링 소요 시간 renderStart ? (startTime + duration) - renderStart: 0
렌더링: 사전 레이아웃 기간 styleAndLayoutStart ? styleAndLayoutStart - renderStart : 0
렌더링: 스타일 및 레이아웃 기간 styleAndLayoutStart ? (startTime + duration) - styleAndLayoutStart : 0

이러한 개별 타이밍에 관한 자세한 내용은 설명을 참고하세요. 이 설명에서는 어떤 활동이 긴 애니메이션 프레임에 기여하는지에 관한 세부적인 정보를 제공합니다.

기여 분석 개선

long-animation-frame 항목 유형에는 긴 애니메이션 프레임에 기여한 각 스크립트의 더 나은 기여 분석 데이터가 포함됩니다.

<ph type="x-smartling-placeholder">

Long Tasks API와 마찬가지로 일련의 기여 분석 항목에 제공됩니다. 각 항목의 세부정보는 다음과 같습니다.

  • nameEntryType는 모두 script를 반환합니다.
  • 스크립트가 호출된 방식을 나타내는 의미 있는 invoker (예: 'IMG#id.onload', 'Window.requestAnimationFrame', 'Response.json.then')
  • 스크립트 진입점의 invokerType: <ph type="x-smartling-placeholder">
      </ph>
    • user-callback: 웹 플랫폼 API (예: setTimeout, requestAnimationFrame)에서 등록된 알려진 콜백입니다.
    • event-listener: 플랫폼 이벤트의 리스너입니다 (예: click, load, keyup).
    • resolve-promise: 플랫폼 프로미스의 핸들러입니다 (예: fetch()). 프로미스의 경우 동일한 프로미스의 모든 핸들러가 하나의 '스크립트')로 혼합됩니다..
    • reject-promise: resolve-promise에 따라 다르지만 거부의 경우
    • classic-script: 스크립트 평가 (예: <script> 또는 import())
    • module-script: classic-script와 동일하지만 모듈 스크립트에 사용됩니다.
  • 해당 스크립트에 대한 별도의 타이밍 데이터: <ph type="x-smartling-placeholder">
      </ph>
    • startTime: 항목 함수가 호출된 시간입니다.
    • duration: startTime과 후속 마이크로태스크 큐의 처리가 완료된 시점 사이의 기간입니다.
    • executionStart: 컴파일 후의 시간입니다.
    • forcedStyleAndLayoutDuration: 이 함수 내의 강제 레이아웃 및 스타일을 처리하는 데 소요된 총 시간입니다 (스래싱 참고).
    • pauseDuration: '일시중지'에 소요된 총시간 동기 작업 (경보, 동기 XHR).
  • 스크립트 소스 세부정보: <ph type="x-smartling-placeholder">
      </ph>
    • sourceURL: 사용 가능한 경우 스크립트 리소스 이름입니다 (또는 찾을 수 없는 경우 비어 있음).
    • sourceFunctionName: 사용 가능한 경우 스크립트 함수 이름입니다 (또는 찾을 수 없는 경우 비어 있음).
    • sourceCharPosition: 사용 가능한 경우 스크립트 문자 위치 (또는 찾을 수 없는 경우 -1)입니다.
  • windowAttribution: 긴 애니메이션 프레임이 발생한 컨테이너 (최상위 문서 또는 <iframe>)입니다.
  • window: 동일 출처 창의 참조입니다.
를 통해 개인정보처리방침을 정의할 수 있습니다. <ph type="x-smartling-placeholder">

소스 항목이 제공되는 경우 개발자는 긴 애니메이션 프레임의 각 스크립트가 호출된 스크립트의 문자 위치까지 정확히 어떻게 호출되었는지 알 수 있습니다. 이렇게 하면 JavaScript 리소스에서 긴 애니메이션 프레임이 발생한 정확한 위치를 알 수 있습니다.

<ph type="x-smartling-placeholder">

long-animation-frame 성능 항목의 예

단일 스크립트가 포함된 전체 long-animation-frame 성능 항목의 예시는 다음과 같습니다.

{
  "blockingDuration": 0,
  "duration": 60,
  "entryType": "long-animation-frame",
  "firstUIEventTimestamp": 11801.099999999627,
  "name": "long-animation-frame",
  "renderStart": 11858.800000000745,
  "scripts": [
    {
      "duration": 45,
      "entryType": "script",
      "executionStart": 11803.199999999255,
      "forcedStyleAndLayoutDuration": 0,
      "invoker": "DOMWindow.onclick",
      "invokerType": "event-listener",
      "name": "script",
      "pauseDuration": 0,
      "sourceURL": "https://web.dev/js/index-ffde4443.js",
      "sourceFunctionName": "myClickHandler",
      "sourceCharPosition": 17796,
      "startTime": 11803.199999999255,
      "window": [Window object],
      "windowAttribution": "self"
    }
  ],
  "startTime": 11802.400000000373,
  "styleAndLayoutStart": 11858.800000000745
}

보시다시피, 이렇게 하면 웹사이트가 지연 렌더링 업데이트의 원인을 파악할 수 있도록 전례 없는 양의 데이터를 확보할 수 있습니다.

필드에 Long Animation Frames API 사용

Chrome DevTools 및 Lighthouse와 같은 도구는 문제를 발견하고 재현하는 데 유용하지만 필드 데이터만 제공할 수 있는 사용자 환경의 중요한 측면을 놓칠 수 있는 실험실 도구입니다.

Long Animation Frames API는 현장에서 Long Tasks API로는 얻을 수 없는 사용자 상호작용에 관한 중요한 문맥 데이터를 수집하는 데 사용되도록 설계되었습니다. 이를 통해 다른 방법으로는 발견하지 못했을 상호작용 관련 문제를 식별하고 재현할 수 있습니다.

Long Animation Frames API 지원 기능 감지

다음 코드를 사용하여 API가 지원되는지 테스트할 수 있습니다.

if (PerformanceObserver.supportedEntryTypes.includes('long-animation-frame')) {
  // Monitor LoAFs
}

Long Animation Frames API의 가장 명백한 사용 사례는 다음 페인트에 대한 상호작용 (INP) 문제를 진단하고 해결하는 것이며, 이것이 Chrome팀에서 이 API를 개발한 주된 이유 중 하나였습니다. 좋은 INP는 프레임이 페인트될 때까지 상호작용으로부터 200밀리초 이내에 모든 상호작용이 응답되는 경우입니다. Long Animation Frames API는 50ms 이상이 걸리는 모든 프레임을 측정하기 때문에 가장 문제가 있는 INP에는 이러한 상호작용을 진단하는 데 도움이 되는 LoAF 데이터가 포함되어야 합니다.

'INP LoAF' 다음 다이어그램과 같이 INP 상호작용이 포함된 LoAF입니다.

<ph type="x-smartling-placeholder">
</ph> INP LoAF가 강조 표시된 페이지의 긴 애니메이션 프레임 예
페이지에 여러 LoAF가 있을 수 있으며 그중 하나는 INP 상호작용과 관련이 있습니다.

경우에 따라 INP 이벤트가 두 개의 LoAF에 걸쳐 있을 수 있습니다. 일반적으로 프레임이 이전 프레임의 렌더링 부분을 시작한 후에 상호작용이 발생하고 따라서 이벤트 핸들러가 다음 프레임에서 처리하는 경우:

<ph type="x-smartling-placeholder">
</ph> INP LoAF가 강조 표시된 페이지의 긴 애니메이션 프레임 예
페이지에 여러 LoAF가 있을 수 있으며 그중 하나는 INP 상호작용과 관련이 있습니다.

드물게는 세 개 이상의 LoAF에 걸쳐 있을 수도 있습니다.

INP 상호작용과 관련된 LoAF 데이터를 기록하면 진단에 도움이 되도록 INP 상호작용에 관한 훨씬 자세한 정보를 얻을 수 있습니다. 이는 해당 프레임에서 실행 중인 다른 스크립트를 확인할 수 있으므로 입력 지연을 이해하는 데 특히 유용합니다.

또한 자체 테스트에 포함되지 않은 다른 스크립트가 사용자를 위해 실행 중일 수 있으므로 이벤트 핸들러가 이러한 값에 대해 표시된 값을 재현하지 않는 경우 설명할 수 없는 처리 기간프레젠테이션 지연을 이해하는 것이 도움이 될 수 있습니다.

INP 항목을 관련 LoAF 항목과 연결하는 직접적인 API는 없지만 코드에서 각 항목의 시작 시간과 종료 시간을 비교하여 연결할 수는 있습니다 (WhyNp 예시 스크립트 참고).

web-vitals 라이브러리에는 v4의 INP 기여 분석 인터페이스의 longAnimationFramesEntries 속성에 교차하는 모든 LoAF가 포함되어 있습니다.

LoAF 항목을 연결하면 INP 저작자 표시가 포함된 정보를 포함할 수 있습니다. scripts 객체는 이러한 프레임에서 실행 중인 다른 작업을 보여줄 수 있으므로 가장 중요한 정보를 포함합니다. 따라서 해당 데이터를 분석 서비스에 비커닝하면 상호작용이 느린 이유를 자세히 파악할 수 있습니다.

INP 상호작용의 LoAF 보고는 페이지에서 가장 긴급한 상호작용 문제가 무엇인지 찾는 좋은 방법입니다. 사용자마다 페이지와 다른 방식으로 상호작용할 수 있으며 충분한 양의 INP 기여 분석 데이터가 있으면 INP 기여 분석 데이터에 잠재적인 문제가 많이 포함됩니다. 이를 통해 볼륨별로 스크립트를 정렬하여 느린 INP와 상관관계가 있는 스크립트를 확인할 수 있습니다.

더 많은 긴 애니메이션 데이터를 분석 엔드포인트에 다시 보고

INP LoAF만 확인하는 한 가지 단점은 향후 INP 문제를 일으킬 수 있는 다른 잠재적 개선 영역을 놓칠 수 있다는 것입니다. 이로 인해 INP 문제를 해결하려고 애쓰는 느낌이 들 수 있습니다. INP는 크게 개선되리라 기대하며 그 다음 가장 느린 상호작용이 그보다 조금 더 나아져서 INP가 크게 개선되지 않는다는 사실을 알게 됩니다.

따라서 INP LoAF만 살펴 보는 것이 아니라 페이지 전체 기간 동안 모든 LoAF를 고려하는 것이 좋습니다.

<ph type="x-smartling-placeholder">
</ph> LoAF가 많은 페이지. 그중 일부는 INP 상호작용이 아니더라도 상호작용 중에 발생합니다.
모든 LoAF를 살펴보면 향후 INP 문제를 식별하는 데 도움이 될 수 있습니다.

그러나 각 LoAF 항목에는 상당한 데이터가 포함되어 있으므로 모두 다시 비콘으로 표시할 필요는 없습니다. 대신 분석을 일부 LoAF 또는 데이터로 제한하는 것이 좋습니다.

권장되는 패턴은 다음과 같습니다.

다음 중 가장 효과적인 패턴은 최적화 여정이 얼마나 진행되었는지와 긴 애니메이션 프레임이 얼마나 일반적인지에 따라 달라집니다. 이전에 반응성에 최적화된 적이 없는 사이트의 경우 LoAF가 많을 수 있습니다. 상호작용으로 LoAF를 제한할 수도 있고, 높은 기준점을 설정할 수도 있고, 가장 좋지 않은 결과만 볼 수도 있습니다. 일반적인 응답성 문제를 해결하면서 상호작용으로 제한하지 않고 기준점을 낮추는 방식으로 문제를 확장하거나 특정 패턴을 찾아낼 수 있습니다.

상호작용이 있는 긴 애니메이션 프레임 관찰

INP 긴 애니메이션 프레임 외에 유용한 정보를 얻으려면 상호작용 (firstUIEventTimestamp 값의 존재로 감지 가능)이 있는 모든 LoAF를 살펴보면 됩니다.

이 방법은 INP LoAF를 모니터링하는 것보다 더 복잡할 수 있으므로 둘의 상관관계를 파악하는 것보다 더 쉬운 방법일 수도 있습니다. 대부분의 경우 여기에는 특정 방문의 INP LoAF가 포함되며, 드물지만 해결해야 하는 긴 상호작용은 다른 사용자의 INP 상호작용일 수 있으므로 해결해야 할 긴 상호작용이 여전히 표시됩니다.

다음 코드는 프레임 중에 상호작용이 발생한 150밀리초보다 큰 모든 LoAF 항목을 기록합니다. 여기서 150은 200밀리초인 '양호'보다 약간 작기 때문에 INP 기준점 필요에 따라 더 높거나 낮은 값을 선택할 수 있습니다.

const REPORTING_THRESHOLD_MS = 150;

const observer = new PerformanceObserver(list => {
    for (const entry of list.getEntries()) {
      if (entry.duration > REPORTING_THRESHOLD_MS &&
        entry.firstUIEventTimestamp > 0
      ) {
        // Example here logs to console, but could also report back to analytics
        console.log(entry);
      }
    }
});
observer.observe({ type: 'long-animation-frame', buffered: true });

특정 기준점보다 긴 애니메이션 프레임 관찰

또 다른 전략은 모든 LoAF를 모니터링하고 특정 임곗값보다 큰 LoAF를 향후 분석을 위해 분석 엔드포인트로 다시 비콘하는 것입니다.

const REPORTING_THRESHOLD_MS = 150;

const observer = new PerformanceObserver(list => {
  for (const entry of list.getEntries()) {
    if (entry.duration > REPORTING_THRESHOLD_MS) {
      // Example here logs to console, but could also report back to analytics
      console.log(entry);
    }
  }
});
observer.observe({ type: 'long-animation-frame', buffered: true });

긴 애니메이션 프레임 항목은 상당히 클 수 있으므로 개발자는 항목에서 애널리틱스로 전송할 데이터를 결정해야 합니다. 예를 들어 항목의 요약 시간과 스크립트 이름 또는 필요하다고 간주될 수 있는 기타 컨텍스트 데이터의 기타 최소 집합 등이 있습니다.

최악의 긴 애니메이션 프레임 관찰

사이트에서는 기준을 설정하는 대신 가장 긴 애니메이션 프레임 (또는 프레임)에서 데이터를 수집하여 비콘을 적용해야 하는 데이터의 양을 줄이려고 할 수 있습니다. 따라서 페이지에 표시되는 애니메이션 프레임의 수와 상관없이 최악의 1개, 5개 또는 그다지 꼭 필요한 긴 애니메이션 프레임의 데이터만 다시 비콘으로 전달됩니다.

MAX_LOAFS_TO_CONSIDER = 10;
let longestBlockingLoAFs = [];

const observer = new PerformanceObserver(list => {
  longestBlockingLoAFs = longestBlockingLoAFs.concat(list.getEntries()).sort(
    (a, b) => b.blockingDuration - a.blockingDuration
  ).slice(0, MAX_LOAFS_TO_CONSIDER);
});
observer.observe({ type: 'long-animation-frame', buffered: true });

이러한 전략을 조합하여 사용할 수도 있습니다. 150밀리초가 넘는 상호작용이 발생한 최악의 LoAF 10개만 살펴볼 수 있습니다.

적절한 시간이 되면 (visibilitychange 이벤트 시) 비콘을 애널리틱스로 다시 보냅니다. 로컬 테스트의 경우 console.table를 주기적으로 사용할 수 있습니다.

console.table(longestBlockingLoAFs);

긴 애니메이션 프레임의 일반적인 패턴 식별

또 다른 전략은 긴 애니메이션 프레임 항목에서 가장 많이 나타나는 일반적인 스크립트를 살펴보는 것입니다. 데이터를 스크립트 및 문자 위치 수준으로 다시 보고하여 반복적으로 위반하는 사용자를 식별할 수 있습니다.

이 기능은 여러 사이트에서 성능 문제를 일으키는 테마나 플러그인을 확인할 수 있는 맞춤형 플랫폼에서 특히 효과적일 수 있습니다.

긴 애니메이션 프레임에서 일반 스크립트(또는 제3자 출처)의 실행 시간을 합산하고 보고하여 한 사이트 또는 사이트 모음에서 긴 애니메이션 프레임의 일반적인 원인을 파악할 수 있습니다. 예를 들어 URL을 확인하는 방법은 다음과 같습니다.

const observer = new PerformanceObserver(list => {
  const allScripts = list.getEntries().flatMap(entry => entry.scripts);
  const scriptSource = [...new Set(allScripts.map(script => script.sourceURL))];
  const scriptsBySource= scriptSource.map(sourceURL => ([sourceURL,
      allScripts.filter(script => script.sourceURL === sourceURL)
  ]));
  const processedScripts = scriptsBySource.map(([sourceURL, scripts]) => ({
    sourceURL,
    count: scripts.length,
    totalDuration: scripts.reduce((subtotal, script) => subtotal + script.duration, 0)
  }));
  processedScripts.sort((a, b) => b.totalDuration - a.totalDuration);
  // Example here logs to console, but could also report back to analytics
  console.table(processedScripts);
});

observer.observe({type: 'long-animation-frame', buffered: true});

이 출력의 예는 다음과 같습니다.

(index) sourceURL count totalDuration
0 'https://example.consent.com/consent.js' 1 840
1 'https://example.com/js/analytics.js' 7 628
2 'https://example.chatapp.com/web-chat.js' 1 5

도구에서 Long Animation Frames API 사용

또한 API를 사용하면 로컬 디버깅을 위한 추가 개발자 도구를 사용할 수 있습니다. Lighthouse 및 Chrome DevTools와 같은 일부 도구는 하위 수준의 추적 세부정보를 사용하여 이러한 데이터의 많은 부분을 수집할 수 있지만, 이 더 높은 수준의 API를 사용하면 다른 도구에서 이 데이터에 액세스할 수 있습니다.

DevTools에 긴 애니메이션 프레임 데이터 표시

performance.measure() API를 사용하여 DevTools에 긴 애니메이션 프레임을 표시할 수 있으며, 이 프레임은 성능 트레이스에서 DevTools 사용자 시간 트랙에 표시되어 성능 개선을 위해 어떤 노력을 집중해야 하는지 보여줍니다.

const observer = new PerformanceObserver((list) => {
  for (const entry of list.getEntries()) {
    performance.measure('LoAF', {
      start: entry.startTime,
      end: entry.startTime + entry.duration,
    });
  }
});

observer.observe({ type: 'long-animation-frame', buffered: true });

장기적으로 DevTools 자체에 통합될 가능성이 높지만, 이전 코드 스니펫을 사용하면 그 동안에도 DevTools에 표시할 수 있습니다.

다른 개발자 도구에서 긴 애니메이션 프레임 데이터 사용

성능 문제를 진단하기 위해 웹 바이탈 확장 프로그램에서 로깅 요약 디버그 정보에 값을 표시했습니다.

이제 각 INP 콜백 및 각 상호작용에 관한 긴 애니메이션 프레임 데이터도 표시합니다.

<ph type="x-smartling-placeholder">
</ph> 웹 바이탈 확장 프로그램 콘솔 로깅
웹 바이탈 확장 프로그램 콘솔 로깅은 LoAF 데이터를 표시합니다.

자동화된 테스트 도구에서 긴 애니메이션 프레임 데이터 사용

이와 유사하게 CI/CD 파이프라인의 자동화된 테스트 도구는 다양한 테스트 모음을 실행하면서 긴 애니메이션 프레임을 측정하여 잠재적인 성능 문제에 관한 세부정보를 드러낼 수 있습니다.

FAQ

이 API에 대해 자주 묻는 질문(FAQ)은 다음과 같습니다.

Long Tasks API를 확장하거나 반복하면 안 되는 이유는 무엇일까요?

이는 잠재적인 대응성 문제에 대한 유사하지만 궁극적으로 다른 측정을 보고하는 또 다른 방법입니다. 기존 Long Tasks API를 사용하는 사이트가 계속 작동하여 기존 사용 사례가 중단되지 않도록 하는 것이 중요합니다.

Long Tasks API는 LoAF의 일부 기능 (예: 더 나은 기여 분석 모델)의 이점을 누릴 수 있지만, 작업보다는 프레임에 집중하면 기존 Long Tasks API와 근본적으로 다른 API가 되는 많은 이점이 있다고 생각합니다.

스크립트 항목이 없는 이유는 무엇인가요?

이는 긴 애니메이션 프레임이 JavaScript가 아니라 대규모 렌더링 작업 때문임을 나타낼 수 있습니다.

이는 긴 애니메이션 프레임이 자바스크립트로 인해 발생하지만 앞서 언급한 다양한 개인 정보 보호 이유로 인해 스크립트 저작자 표시를 제공할 수 없는 경우 (주로 자바스크립트가 페이지에서 소유하지 않은 경우)에도 발생할 수 있습니다.

스크립트 항목에 소스 정보가 없거나 제한된 이유는 무엇인가요?

이는 가리킬 수 있는 적절한 출처가 없는 경우 등 여러 가지 이유로 발생할 수 있습니다.

no-cors cross-origin 스크립트에 대해서도 스크립트 정보가 제한되지만 <script> 호출에 crossOrigin = "anonymous"를 추가하여 CORS를 사용하여 해당 스크립트를 가져오면 이 문제를 해결할 수 있습니다.

예를 들어 페이지에 추가할 기본 Google 태그 관리자 스크립트는 다음과 같습니다.

<!-- Google Tag Manager -->
<script>(function(w,d,s,l,i){w[l]=w[l]||[];w[l].push({'gtm.start':
new Date().getTime(),event:'gtm.js'});var f=d.getElementsByTagName(s)[0],
j=d.createElement(s),dl=l!='dataLayer'?'&l='+l:'';j.async=true;j.src=
'https://www.googletagmanager.com/gtm.js?id='+i+dl;f.parentNode.insertBefore(j,f);
})(window,document,'script','dataLayer','GTM-XXXXXXX');</script>
<!-- End Google Tag Manager -->

j.crossOrigin = "anonymous"를 추가하여 GTM에 대한 전체 기여 분석 세부정보를 제공할 수 있도록 개선할 수 있음

Long Tasks API를 대체하나요?

Long Animation Frames API가 장기 작업을 측정하는 더 우수하고 완전한 API라고 생각하지만, 현재 Long Tasks API를 지원 중단할 계획은 없습니다.

의견 요청

의견은 GitHub 문제 목록에서 제공할 수 있으며, Chrome의 API 구현 버그는 Chrome Issue Tracker에서 제출할 수 있습니다.

결론

Long Animation Frames API는 이전의 Long Tasks API에 비해 많은 잠재적인 이점이 있는 흥미롭고 새로운 API입니다.

INP에서 측정한 응답성 문제를 해결하기 위한 핵심 도구임이 입증되고 있습니다. INP는 최적화하기가 어려운 측정항목이며, 이 API는 Chrome팀이 개발자를 위해 문제를 더 쉽게 식별하고 해결할 수 있도록 하는 방법 중 하나입니다.

Long Animation Frames API의 범위는 INP에 국한되지 않으며, 웹사이트 사용자 환경의 전반적인 원활에 영향을 줄 수 있는 느린 업데이트의 다른 원인을 파악하는 데 도움이 될 수 있습니다.

감사의 말씀

Unsplash헨리 비의 썸네일 이미지