이 명세는 웹 애플리케이션이 샘플링 프로파일러를 제어하여 클라이언트의 JavaScript 실행 시간을 측정할 수 있도록 하는 API를 설명합니다.

소개

현재 복잡한 웹 애플리케이션은 클라이언트에서 JS 실행 시간이 어디에 소요되는지 파악하는 데 한계가 있습니다. 효율적으로 스택 샘플을 수집할 수 없으면, 애플리케이션은 코드에 부정확하고 실행 속도를 크게 저하시킬 수 있는 프로파일링 훅을 삽입해야 합니다. 샘플링 프로파일러를 조작하는 API를 제공하면, 애플리케이션은 집계와 분석에 사용할 풍부한 실행 데이터를 최소한의 오버헤드로 수집할 수 있습니다.

예제

다음 예제는 사용자가 비용이 많이 드는 연산을 프로파일링하면서 JS 실행 샘플을 10ms마다 수집하는 방법을 보여 줍니다. 트레이스를 서버로 전송하여 이상치를 디버깅하고 JS 실행 특성을 종합적으로 분석할 수 있습니다.

        const profiler = new Profiler({ sampleInterval: 10, maxBufferSize: 10000 });
        const start = performance.now();
        for (let i = 0; i < 1000000; i++) {
             doWork();
        }
        const duration = performance.now() - start;
        const trace = await profiler.stop();
        const traceJson = JSON.stringify({
          duration,
          trace,
        });
        sendTrace(traceJson);
        

또 다른 일반적인 실제 사용 사례는 페이지 로드 전반에 걸친 JS 프로파일링입니다. 이 예제는 onload 이벤트를 프로파일링하고, 트레이스와 함께 성능 타이밍 데이터를 전송합니다.

        const profiler = new Profiler({ sampleInterval: 10, maxBufferSize: 10000 });

        window.addEventListener('load', async () => {
          const trace = await profiler.stop();
          const traceJson = JSON.stringify({
            timing: performance.timing,
            trace,
          });
          sendTrace(traceJson);
        });

        // 페이지의 나머지 JS 초기화 로직
        

정의

샘플은 특정 시점의 순간적인 실행 상태를 설명하는 정보입니다. 각 샘플은 스택과 연결됩니다.

스택은 프레임 목록이며, 가장 바깥쪽 프레임부터 가장 안쪽 프레임까지 순서대로 정렬되어야 합니다.

프레임은 스택의 컨텍스트 내 요소로, 현재 실행 상태에 관한 정보를 포함합니다.

프로파일링 세션

프로파일링 세션은 샘플을 생성하는 추상적인 생성자입니다. 각 세션에는 다음이 있습니다:

  1. {started, paused, stopped} 중 하나인 상태.
  2. 세션이 샘플을 얻는 주기로 정의되는 샘플링 간격.

    UA가 이 주기로 샘플을 채취할 필요는 없습니다. 그러나 더 높은 품질의 트레이스를 생성하기 위해 이 주기로 샘플을 채취하도록 샘플링에 우선순위를 부여하는 것이 권장됩니다.

  3. 프로파일링할 에이전트.
  4. 프로파일링할 렐름.
  5. 샘플의 타임스탬프를 측정할 때 기준으로 삼는 시간 원점.
  6. 샘플 버퍼 크기 제한.
  7. 캡처한 샘플을 저장하는 ProfilerTrace.

같은 페이지에서 여러 프로파일링 세션을 지원하는 것이 권장됩니다.

상태

started 상태에서 UA는 최선을 다해 샘플 채취 알고리즘을 [= in parallel =]로 실행하여 샘플링 간격이 경과할 때마다 샘플을 캡처하는 것이 권장됩니다. paused 및 stopped 상태에서는 UA가 샘플을 캡처하지 않는 것이 권장됩니다.

프로파일링 세션은 started 상태에서 시작해야 합니다.

UA는 세션을 started에서 paused로, 그리고 paused에서 started로 전환할 수 있습니다.

브라우징 컨텍스트가 전경에 있지 않으면 사용자 에이전트가 프로파일링 세션의 샘플링을 일시 중지하는 것이 권장됩니다.

stopped 세션은 started 또는 paused 상태로 전환되어서는 안 됩니다.

처리 모델

프로파일링 세션이 주어졌을 때 샘플 채취를 수행하려면 다음 단계를 수행합니다:

  1. ProfilerTrace.samples의 길이가 프로파일링 세션과 연결된 샘플 버퍼 크기 제한보다 크거나 같으면, 연결된 Profiler에 samplebufferfull 유형의 새 이벤트를 발생시키고, 상태를 stopped로 전환한 다음, 반환합니다.
  2. sample을 새 ProfilerSample로 설정합니다.
  3. sample의 ProfilerSample.timestamp 속성을 현재 고해상도 시간으로 설정하되, 프로파일링 세션의 시간 원점을 기준으로 합니다.
  4. stack을 실행 컨텍스트 스택으로 설정하되, 프로파일링 세션의 에이전트와 연결된 것을 사용합니다.
  5. sample의 ProfilerSample.stackId 속성을 스택 ID 가져오기 알고리즘을 stack에 대해 실행한 결과로 설정합니다.
  6. marker를 마커 캡처 알고리즘의 실행 결과로 설정하되, 프로파일링 세션에 연결된 환경 설정 객체를 전달합니다.
  7. marker가 null이 아니면, sample의 ProfilerSample.marker 속성을 marker로 설정합니다.
  8. sample을 세션의 ProfilerTrace와 연결된 ProfilerTrace.samples에 추가합니다.

환경 설정 객체 settings가 주어졌을 때 마커 캡처를 수행하려면 다음 단계를 수행합니다:

  1. candidateMarker를 최상위 작업을 가장 잘 설명하는 ProfilerMarker 값으로 설정하되, 사용자 에이전트가 샘플 채취 시 프로파일링 세션의 에이전트에서 수행하던 작업을 기준으로 하며, null로 설정하는 경우는 해당하는 값이 없을 때입니다.
  2. candidateMarker가 null이면, null을 반환합니다.
  3. candidateMarker가 설명하는 작업이 특정 문서에 대해 수행되었으며, 해당 문서가 [= same origin =]이 아닌 대상이 출처이고 그 소유자가 settings이면, null을 반환합니다.
  4. candidateMarker와 settings를 전달하여 마커 필터링을 실행한 결과를 반환합니다.

사용자 에이전트의 내부 활동을 ProfilerMarker 값에 대응시키는 방식은 의도적으로 구현에서 정의하도록 합니다. 엔진 아키텍처가 서로 다르기 때문입니다. 비규범적 지침으로, 사용자 에이전트는 작성자 스크립트를 실행하는 동안 script를, 가비지 컬렉션 중에는 gc를, 계산된 스타일을 다시 계산하는 동안 style을, 박스의 기하 정보를 계산하는 동안 layout을 (즉, 리플로), 문서 콘텐츠를 래스터화하거나 합성하는 동안 paint를 보고할 것으로 기대됩니다. other 마커는 앞서 나열한 범주에 속하지 않는 사용자 에이전트 작업에 사용됩니다. 적용되는 범주가 없으면(예를 들어, 에이전트가 유휴 상태이면), 마커 캡처 알고리즘은 null을 반환하고, 결과의 ProfilerSample.marker 속성은 ProfilerSample에 존재하지 않는 상태로 남습니다.

동일 출처 검사는 마커가 프로파일러와 [= same origin =]인 문서에 대해 수행된 작업만 설명하도록 보장하며, 이는 API가 교차 출처 활동을 드러내지 않아야 한다는 요구사항과 일치합니다. 작업이 단일 문서에 귀속될 수 없다면 — 예를 들어, 엔진 전체의 가비지 컬렉션 — 이 작업은 해당 검사의 제약을 받지 않습니다. 대신 이러한 작업은 프로파일러가 교차 출처 격리 상태일 때만 공개되며, 이는 마커 필터링에 의해 적용됩니다.

ProfilerMarker marker와 환경 설정 객체 settings가 주어졌을 때 마커 필터링을 수행하려면, 다음 단계를 수행합니다:

  1. settings의 교차 출처 격리 기능이 true이면, marker를 반환합니다.
  2. marker가 "style" 또는 "layout"이면, marker를 반환합니다.
  3. null을 반환합니다.

마커 필터링 알고리즘은 교차 출처 격리 상태가 아닌 컨텍스트에서 style 및 layout 마커만 ProfilerSample에 나타나는 관찰 가능한 동작을 만듭니다. script, gc, paint 및 other 마커는 억제됩니다. 조건부 마커 공개에서 이 동작의 근거를 설명합니다. 사용자 에이전트는 명시적 참여 메커니즘(예를 들어, 오리진 트라이얼 토큰 또는 문서 정책)을 제공하여 마커 필터링이 반환하는 집합을 특정 환경 설정 객체에 대해 확장할 수 있습니다. 이러한 명시적 참여는 출처를 넘어 마커를 공개해서는 안 됩니다.

stack에 바인딩된 실행 컨텍스트 스택이 주어졌을 때 스택 ID 가져오기를 수행하려면, 다음 단계를 수행합니다:

  1. stack이 비어 있으면, undefined를 반환합니다.
  2. head를 stack의 최상위 요소로 설정하고, tail을 stack에서 최상위 요소를 제거한 나머지로 설정합니다.
  3. parentId를 tail에 대해 스택 ID 가져오기를 재귀적으로 호출한 결과로 설정합니다.
  4. frameId를 head에 대해 프레임 ID 가져오기를 호출한 결과로 설정합니다.
  5. frameId가 undefined이면, parentId를 반환합니다.
  6. profilerStack을 새 ProfilerStack으로 설정하되, ProfilerStack.frameId가 frameId와 같고, ProfilerStack.parentId가 parentId와 같도록 합니다.
  7. profilerStack과 ProfilerTrace.stacks에 대해 요소 ID 가져오기를 실행한 결과를 반환합니다.

context에 바인딩된 실행 컨텍스트가 주어졌을 때 프레임 ID 가져오기를 수행하려면 다음 단계를 수행합니다:

  1. context와 연결된 [= realm =]이 프로파일링 세션과 연결된 렐름과 일치하지 않으면, undefined를 반환합니다.
  2. instance를 함수 인스턴스와 같게 설정하되, context와 연결된 것을 사용합니다.
  3. scriptOrModule을 context와 연결된 ScriptOrModule과 같게 설정합니다.
  4. |attributedScriptOrModule : ScriptOrModule|을 다음 알고리즘을 실행한 결과와 같게 설정합니다:
    1. |scriptOrModule|이 null이 아니면, |scriptOrModule|을 반환합니다.
    2. |instance|가 내장 함수 객체이면, |instance|를 호출한 함수를 포함하는 ScriptOrModule을 반환합니다.

      위 로직의 목적은 접근할 수 없는 스크립트가 호출한 내장 함수가 트레이스에 공개되지 않도록 보장하는 것이며, 이를 위해 해당 함수를 호출한 ScriptOrModule을 귀속 대상으로 사용합니다.

      "[...] |instance|를 호출한 함수를 포함하는 ScriptOrModule"은 더 엄밀하게 정의해야 합니다. 이를 위해 스택에서 ScriptOrModule을 정의하는 최상위 실행 컨텍스트를 활용할 수 있지만, 이상적이지는 않습니다 -- 내장 함수가 실행 컨텍스트 스택에 추가되는 다른 메커니즘이 (이론적으로) 존재할 수 있으며, 이 경우 해당 귀속은 유효하지 않기 때문입니다.

    3. 그렇지 않으면, null을 반환합니다.
  5. |attributedScriptOrModule|이 null이면, undefined를 반환합니다.
  6. |attributedScript : Script|를 |attributedScriptOrModule|.[[\HostDefined]]에서 얻은 [= script =]로 설정합니다.
  7. |attributedScript|가 [= classic script =]이고 그 오류 음소거 불리언이 true와 같으면, undefined를 반환합니다.

    이 검사는 CORS 교차 출처 응답으로 제공된 교차 출처 스크립트의 스택 프레임이 포함되지 않도록 보장합니다. 이 사용 사례를 더 잘 반영하도록 오류 음소거의 이름을 바꾸는 것을 고려할 수 있습니다.

  8. frame을 새 ProfilerFrame으로 설정합니다.
  9. frame의 ProfilerFrame.name을 함수 인스턴스 이름으로 설정하되, |instance|와 연결된 것을 사용합니다.
  10. |scriptOrModule|이 null이 아니면:
    1. script를 스크립트로 설정하되, scriptOrModule.[[\HostDefined]]에서 얻은 것을 사용합니다.
    2. resourceString을 기준 URL과 같게 설정하되, script의 것을 사용합니다.
    3. ProfilerFrame.resourceId를 요소 ID 가져오기의 실행 결과로 설정하되, resourceString과 ProfilerTrace.resources를 전달합니다.
    4. frame의 ProfilerFrame.line을 줄의 1부터 시작하는 인덱스로 설정하되, |script|에서 instance가 정의된 줄을 사용합니다.
    5. frame의 ProfilerFrame.column을 열의 1부터 시작하는 인덱스로 설정하되, |script|에서 instance가 정의된 열을 사용합니다.
  11. frame과 ProfilerTrace.frames에 대해 요소 ID 가져오기를 실행한 결과를 반환합니다.

list에 있는 item의 요소 ID 가져오기를 수행하려면 다음 단계를 실행합니다:

  1. list에 구성 요소별로 item과 같은 요소가 있으면, 그 인덱스를 반환합니다.
  2. 그렇지 않으면, item을 list의 끝에 추가하고 그 인덱스를 반환합니다.

Profiler 인터페이스

      [Exposed=(Window, Worker)]
      interface Profiler : EventTarget {
        readonly attribute DOMHighResTimeStamp sampleInterval;
        readonly attribute boolean stopped;

        constructor(ProfilerInitOptions options);
        Promise<ProfilerTrace> stop();
      };
      

각 Profiler는 정확히 하나의 프로파일링 세션과 연결되어야 합니다.

sampleInterval 속성은 연결된 프로파일링 세션의 샘플링 간격을 DOMHighResTimeStamp로 표현한 값을 반영해야 합니다.

stopped 속성은 프로파일링 세션의 상태가 다음과 같은 경우에만 true여야 합니다: stopped.

new Profiler(options)

new Profiler(options)는 객체 options가 다음 유형으로 주어졌을 때 다음 단계를 실행합니다: ProfilerInitOptions:
  1. options의 {{ProfilerInitOptions/sampleInterval}}이 0보다 작으면, RangeError를 던집니다.
  2. |globalObject|를 현재 전역 객체로 설정합니다.
  3. |globalObject|가 Window 또는 WorkerGlobalScope이면:
    1. 가져오기: 정책 값을 "js-profiling-mode"에 대해 |globalObject|에서 수행합니다. |profilingMode|를 그 결과로 설정합니다.
    2. |profilingMode|가 "eager"도 "lazy"도 아니면:
      1. 가져오기: 정책 값을 "js-profiling"에 대해 |globalObject|에서 수행합니다. |jsProfilingEnabled|를 그 결과로 설정합니다.
      2. |jsProfilingEnabled|가 false이면, "NotAllowedError" DOMException을 던집니다.
  4. 그렇지 않으면, "NotAllowedError" DOMException을 던집니다.
  5. 다음 조건을 만족하는 새 프로파일링 세션을 생성합니다:
    1. 연결된 샘플링 간격을 ProfilerInitOptions.sampleInterval 또는 UA가 지원하는 바로 다음으로 짧은 간격으로 설정합니다.
    2. 연결된 시간 원점은 |globalObject|의 시간 원점과 같습니다.
    3. 연결된 샘플 버퍼 크기 제한을 {{ProfilerInitOptions/maxBufferSize}}로 설정합니다.
    4. 연결된 [= agent =]를 주변 에이전트로 설정합니다.
    5. 연결된 [= realm =]을 현재 렐름 레코드로 설정합니다.
    6. 연결된 ProfilerTrace를 다음과 같이 설정합니다: «[{{ProfilerTrace/resources}} → «», {{ProfilerTrace/frames}} → «», {{ProfilerTrace/stacks}} → «», {{ProfilerTrace/samples}} → «»]».
  6. 새로 생성한 프로파일링 세션과 연결된 새 Profiler를 반환합니다.

stop() 메서드

프로파일러를 중지하고 트레이스를 반환합니다. 이 메서드는 다음 단계를 실행해야 합니다:

  1. 연결된 [= profiling session =]의 상태가 stopped이면, [= a promise rejected with =]를 "InvalidStateError" DOMException으로 반환합니다.
  2. [= profiling session =]의 상태를 stopped로 설정합니다.
  3. |p:Promise|를 [= a new promise =]로 설정합니다.
  4. 다음 단계를 [= in parallel =]로 실행합니다:
    1. [= profiling session =]을 중지하기 위한 [= implementation-defined =] 작업을 수행합니다.
    2. |p|를 프로파일러의 [= profiling session =]과 연결된 {{ProfilerTrace}}로 이행합니다.
  5. |p|를 반환합니다.

stop()이 호출된 후 채취된 샘플은 프로파일링 세션에 포함하지 않는 것이 권장됩니다.

ProfilerTrace 딕셔너리

      typedef DOMString ProfilerResource;

      dictionary ProfilerTrace {
        required sequence<ProfilerResource> resources;
        required sequence<ProfilerFrame> frames;
        required sequence<ProfilerStack> stacks;
        required sequence<ProfilerSample> samples;
      };
      

resources 속성은 샘플 채취 알고리즘이 설정한 ProfilerResource 목록을 반환해야 합니다.

frames 속성은 샘플 채취가 설정한 ProfilerFrame 목록을 해당 알고리즘에 따라 반환해야 합니다.

stacks 속성은 샘플 채취가 설정한 ProfilerStack 목록을 해당 알고리즘에 따라 반환해야 합니다.

samples 속성은 샘플 채취가 설정한 ProfilerSample 목록을 해당 알고리즘에 따라 반환해야 합니다.

이 표현은 V8 트레이스 이벤트 형식 및 Gecko 프로파일 형식에서 영감을 받아, 쉽고 효율적으로 직렬화할 수 있도록 설계되었습니다.

ProfilerSample 딕셔너리

        enum ProfilerMarker { "script", "gc", "style", "layout", "paint", "other" };

        dictionary ProfilerSample {
          required DOMHighResTimeStamp timestamp;
          unsigned long long stackId;
          ProfilerMarker? marker;
        };
        

timestamp는 초기화된 값을 반환해야 합니다.

stackId는 초기화된 값을 반환해야 합니다.

marker는 샘플 채취 알고리즘에 의해 초기화된 값을 반환하거나, 마커가 설정되지 않았다면 존재하지 않아야 합니다. 공개될 수 있는 마커 값의 집합은 마커 필터링 알고리즘에 의해 결정됩니다.

교차 출처 격리 컨텍스트에서 마커 필터링 알고리즘은 ProfilerMarker 열거형의 모든 값을 반환합니다. 격리되지 않은 컨텍스트에서는 style과 layout만 반환하므로, 다른 모든 마커는 억제됩니다(marker 속성은 해당 ProfilerSample에 존재하지 않습니다).

ProfilerStack 딕셔너리

        dictionary ProfilerStack {
          unsigned long long parentId;
          required unsigned long long frameId;
        };
        

parentId는 초기화된 값을 반환해야 합니다.

frameId는 초기화된 값을 반환해야 합니다.

ProfilerFrame 딕셔너리

        dictionary ProfilerFrame {
          required DOMString name;
          unsigned long long resourceId;
          unsigned long long line;
          unsigned long long column;
        };
        

name은 초기화된 값을 반환해야 합니다.

resourceId는 초기화된 값을 반환해야 합니다.

line은 초기화된 값을 반환해야 합니다.

column은 초기화된 값을 반환해야 합니다.

ProfilerInitOptions 딕셔너리

      dictionary ProfilerInitOptions {
        required DOMHighResTimeStamp sampleInterval;
        required unsigned long maxBufferSize;
      };
      

ProfilerInitOptions는 다음 필드를 지원해야 합니다:

문서 정책

이 명세는 설정 지점을 문서 정책에 정의하여 프로파일링 기능과 초기화 동작을 제어합니다.

js-profiling-mode

이 명세는 설정 지점을 js-profiling-mode라는 이름으로 정의합니다. 그 유형 은 enum이며, 허용되는 값은 "eager"와 "lazy"입니다. 기본 값은 빈 문자열입니다.

설정되면, 이 정책은 스크립트가 JS 자체 프로파일링 API를 사용할 수 있도록 허용합니다.

eager

js-profiling-mode가 "eager"로 설정되면, UA에 페이지 로드 중 프로파일링이 예상됨을 알립니다.

UA는 이 힌트를 사용하여 프로파일링 기반 기능을 조기에 초기화하고, 필요한 메타데이터를 저장하며 문서 로드 중 가능한 한 빨리 프로파일링 구성 요소를 준비할 수 있습니다. 그러나 프로파일링을 실제로 사용하지 않더라도 상당한 성능 오버헤드가 발생할 수 있습니다. 이러한 오버헤드는 최초 콘텐츠풀 페인트(FCP) 및 최대 콘텐츠풀 페인트(LCP)와 같은 지표에 부정적인 영향을 줄 수 있습니다.

lazy

js-profiling-mode가 "lazy"로 설정되면, UA에 프로파일링이 조건부로 사용될 것임을 알립니다.

UA는 이 힌트를 사용하여 프로파일링 관련 초기화 오버헤드를 최초의 Profiler가 인스턴스화될 때까지 지연함으로써, 프로파일링을 실제로 사용하지 않을 때 중요한 렌더링 기간의 성능 비용을 피할 수 있습니다. 그러나 사용자 상호작용을 처리하는 동안 초기화가 발생하면, 다음 페인트까지의 상호작용(INP)에 부정적인 영향을 줄 수 있습니다. 이 모드는 특히 샘플링 결정에 따라 조건부로 프로파일링을 활성화하는 문서에 적합합니다.

js-profiling (사용 중단됨)

이 명세는 또한 설정 지점을 js-profiling이라는 이름으로 정의합니다. 그 유형 은 boolean이며, 기본 값은 false입니다.

활성화되면, 이 정책은 스크립트가 JS 자체 프로파일링 API를 사용할 수 있도록 허용하고 UA에 프로파일링 기반 기능을 조기에 초기화하도록 알립니다(의미상 js-profiling-mode=eager와 동일합니다).

js-profiling 불리언 설정 지점은 사용이 중단되었으며, 대신 js-profiling-mode를 사용합니다. 둘 다 지정되면, js-profiling-mode가 우선하며 js-profiling은 무시해야 합니다. 구현은 js-profiling을 지원하는 것이 권장됩니다. 이는 하위 호환성을 위한 것이지만, 향후 지원을 제거할 수 있습니다.

자동화

사용자 에이전트 자동화 및 애플리케이션 테스트를 위해, 이 문서는 다음 [[WebDriver]] 확장 명령을 정의합니다.

강제 샘플 채취

HTTP 메서드 URI 템플릿
POST `/session/{session id}/forcesample`

강제 샘플 채취 확장 명령은 더 결정적인 테스트를 가능하게 하기 위해 모든 [=profiling sessions=]가 [=take a sample=]을 수행하도록 강제합니다.

원격 끝점 단계는 다음과 같습니다:

  1. |sessions:list|를 모든 [=profiling sessions=]의 [=list=]로 설정하되, 이 세션들은 현재 브라우징 컨텍스트에서 생성된 것입니다.
  2. |sessions|의 각 |session:profiling session|에 대해:
    1. |session|의 [=state=]가 started이면, |session|으로 [=take a sample=]을 수행합니다.
  3. 데이터 null과 함께 성공을 반환합니다.

개인정보 보호 및 보안

다음 절에서는 API의 개인정보 보호 및 보안 관련 선택 사항 일부를 자세히 설명하고, 다양한 유형의 공격에 대한 보호 전략을 보여 줍니다.

교차 출처 스크립트 콘텐츠

API는 교차 출처 스크립트의 콘텐츠가 공개되지 않도록, 다음을 통해 포함되는 모든 함수가 샘플 채취 알고리즘에 의해 CORS 동일 출처로 제공된 스크립트에 정의되어 있어야 함을 오류 음소거 속성을 통해 요구합니다. 브라우저 내장 함수(예: performance.now()) 또한 [= CORS-same-origin =] 스크립트에서 호출될 때만 포함되어야 합니다.

따라서 API는 교차 출처 스크립트의 콘텐츠나 실행 특성에 대해 수동 계측으로 이미 파악할 수 있는 것 이상의 새로운 정보를 공개하지 않습니다. UA가 매우 짧은 샘플링 간격 값(예: 1밀리초 미만)을 지원하기로 선택한다면, 이 원칙이 유지되는지 확인하는 것이 권장됩니다.

교차 출처 실행

교차 출처 실행 컨텍스트는 샘플 채취 알고리즘의 렐름 검사를 통해 API에서 관찰할 수 없도록 하는 것이 권장됩니다. 교차 출처 iframes 및 프로파일러와 에이전트를 공유하는 다른 실행 컨텍스트의 실행은 따라서 이 API를 통해 관찰할 수 없습니다.

타이밍 공격

고해상도 타이밍 정보의 새로운 출처를 도입할 수 있는 모든 API에서 타이밍 공격은 여전히 우려 사항입니다. 트레이스에서 수집하는 타임스탬프는 [[?HR-Time]]의 현재 고해상도 시간과 같은 출처에서 얻어, 새로운 부채널 공격 경로가 노출되지 않도록 하는 것이 권장됩니다.

[[?HR-Time]]의 시계 해상도에 관한 설명을 참조하세요.

조건부 마커 공개

기본적으로, 마커 필터링 알고리즘은 script, gc, paint 및 other 마커를 프로파일러의 환경 설정 객체가 자신의 교차 출처 격리 기능을 true로 설정한 경우에만 공개합니다. 이러한 마커는 확실하게 귀속시킬 수 없는 엔진 작업을 반영할 수 있습니다. 그 대상은 단일 출처입니다 — 예를 들어, 가비지 컬렉션 및 기타 컨텍스트 간 엔진 활동은 여러 컨텍스트의 작업을 상호 연관시킬 수 있으며, 페인팅은 다른 프레임의 콘텐츠를 합성할 수 있습니다. 따라서 격리 없이 이러한 작업의 타이밍을 공개하면 교차 출처 부채널에 기여할 수 있으며, 이는 교차 출처 격리가 완화하도록 설계된 유형이므로, 격리를 조건으로 공개합니다. 사용자 에이전트는 공개되는 집합을 명시적 참여를 통해 확장할 수 있지만(위의 마커 필터링 참고에서 설명한 대로), 이러한 명시적 참여는 출처를 넘어 마커를 공개해서는 안 됩니다.

style 및 layout 마커는 교차 출처 격리 없이 공개됩니다. 이 마커가 드러내는 타이밍은 이미 동일 출처에서 관찰할 수 있기 때문입니다. 문서는 이미 동기적으로 자신의 스타일과 레이아웃을 플러시하고, 그 시간을 기존 API로 측정할 수 있습니다 — 예를 들어, getBoundingClientRect()는 레이아웃을 강제하고, getComputedStyle()은 스타일을 플러시합니다. (필요한 경우 레이아웃도 플러시합니다). 이 속성을 유지하기 위해, 마커 캡처 알고리즘은 프로파일러와 동일 출처인 문서에 대해 수행된 작업에 대해서만 마커를 보고합니다. 작업을 동일 출처 문서에 귀속시킬 수 없으면 이러한 마커를 통해 보고하지 않습니다. 따라서 이 마커는 동일 출처 문서가 이미 스스로 얻을 수 있는 것 이상의 타이밍 정보를 공개하지 않습니다.