컴퓨트 프레셔 레벨 1

W3C 후보 권고안 초안

이 문서에 대한 자세한 정보
이 버전:
https://www.w3.org/TR/2025/CRD-compute-pressure-20250521/
최신 공식 버전:
https://www.w3.org/TR/compute-pressure/
최신 편집자 초안:
https://w3c.github.io/compute-pressure/
역사:
https://www.w3.org/standards/history/compute-pressure/
커밋 내역
테스트 슈트:
https://github.com/web-platform-tests/wpt/labels/compute-pressure
구현 보고서:
https://wpt.fyi/results/compute-pressure
편집자:
Kenneth Rohde Christiansen (Intel Corporation)
Arnaud Mandy (Intel Corporation)
이전 편집자:
Raphael Kubo da Costa (Intel Corporation)
피드백:
GitHub w3c/compute-pressure (풀 리퀘스트, 이슈 등록, 오픈 이슈)

개요

Compute Pressure API는 웹사이트가 대상 장치의 CPU 부하 변화에 반응하여, 웹사이트가 리소스를 조율함으로써 더 나은 사용자 경험을 제공할 수 있도록 합니다.

이 문서의 상태

이 섹션은 문서가 발행된 시점에서의 상태를 설명합니다. 현재 W3C 발행물 목록과 이 기술 보고서의 최신 개정본은 W3C 표준 및 초안 색인에서 https://www.w3.org/TR/에서 확인할 수 있습니다.

이 명세가 CR 단계를 벗어나기 위해서는, 명세에서 정의한 모든 기능이 각각 최소 2개의 독립적인 구현으로 구현 보고서에 문서화되어야 합니다.

이 문서는 디바이스 및 센서 워킹 그룹에서 권고안 절차를 사용하여 후보 권고안 초안으로 발행한 것입니다.

후보 권고안으로 발행된다고 해서 W3C 및 회원의 승인을 의미하지는 않습니다. 후보 권고안 초안은 워킹 그룹이 다음 후보 권고안 스냅샷에 포함하려는 이전 후보 권고안의 변경사항을 통합합니다.

이 문서는 초안이며, 언제든지 갱신, 대체 또는 폐기될 수 있습니다. 진행 중인 작업 이외의 용도로는 인용에 적합하지 않습니다.

이 문서는 W3C 특허 정책에 따라 운영되는 그룹에서 제작되었습니다. W3C는 해당 그룹 산출물과 관련하여 이루어진 공개 특허 공개 목록 을 관리합니다. 해당 페이지에는 특허 공개 방법에 관한 안내도 포함되어 있습니다. 특정 특허가 필수 청구항 을 포함한다고 실제로 알고 있는 개인은 W3C 특허 정책 6항에 따라 공개해야 합니다.

이 문서는 2023년 11월 3일자 W3C 프로세스 문서의 적용을 받습니다.

1. 소개

이 섹션은 비규범적입니다.

최신 애플리케이션은 즐겁고 현대적인 사용자 경험을 제공하기 위해 시스템의 컴퓨팅 자원을 최대한 활용하는 것의 장점과 단점을 균형 있게 고려해야 합니다.

예를 들어, 많은 애플리케이션들이 다양한 수준의 정교함으로 비디오 효과를 렌더링할 수 있습니다. 이러한 애플리케이션들은 최고의 사용자 경험을 제공하면서도 사용자의 디바이스가 높은 부하 상태에 들어가지 않도록 주의합니다.

처리 유닛의 활용도가 100%에 근접하거나 도달할 경우, 여러 작업이 처리 시간을 두고 경쟁하게 되어 사용성 저하가 발생할 수 있습니다. 이는 특히 입력 지연에서 두드러지는 느려짐으로 이어질 수 있습니다. 또한, 오랜 시간 동안 100%에 가까운 활용도가 지속되면 처리 유닛이 지속적인 부스트로 인해 과열되고, 이는 쓰로틀링을 야기해 더욱 좋지 않은 사용자 경험을 남길 수 있습니다.

열적 한계로 인해 많은 스마트폰, 태블릿, 노트북이 만졌을 때 불편할 정도로 뜨거워질 수 있습니다. 노트북과 데스크탑의 팬 소음은 대화나 사용자 집중을 방해할 정도로 커질 수 있습니다.

많은 경우, 높은 부하 속의 디바이스는 응답하지 않는 것처럼 보일 수 있는데, 운영체제가 사용자가 기다리는 작업을 진행시키는 스레드의 스케줄링에 실패할 수 있기 때문입니다. 더 자세한 내용은 사용 사례를 참고하세요.

2. 기능 탐지에 대한 참고

이 섹션은 비규범적입니다.

기능 탐지는 확립된 웹 개발 모범 사례입니다. 관련 자료는 온오프라인에 풍부하게 존재하며, 이 절의 목적은 해당 주제를 자세히 다루는 것이 아니라, 하드웨어 의존 기능 탐지의 맥락에 두고 설명하는 데 있습니다.

아래의 기능 탐지 예시를 고려해보세요:

참고

3. 개념

본 명세는 다음과 같은 개념을 정의합니다:

3.1 처리 유닛

컴퓨팅 디바이스는 중앙 처리 장치(CPU), 그래픽 처리 장치(GPU) 및 다양한 특화된 처리 유닛과 같은 처리 유닛으로 구성됩니다. 후자의 경우 머신러닝이나 컴퓨터 비전 등 특정 작업을 가속화하도록 설계된 유닛이 점점 더 대중화되고 있습니다.

3.2 부하 소스

본 명세는 유효한 소스 타입중앙 처리 유닛, 즉 CPU로 정의하고 있습니다. 명세의 미래 레벨에서는 추가적인 소스 타입이 도입될 수 있습니다.

PressureSource 열거형은 유효한 소스 타입을 나타냅니다:

참고

3.3 샘플링 및 보고 주기

요청된 샘플링 간격은 하드웨어에서 샘플을 얻는 간격을 밀리초(ms) 단위로 지정합니다.

간격과 주파수는 서로 역수 관계이므로, 요청된 샘플링 간격은 1000을 해당 값으로 나누어 헤르츠(초당 회전수) 단위의 요청된 샘플링 주기로도 표현할 수 있습니다.

샘플링 주기플랫폼 콜렉터가 하위 플랫폼에서 텔레메트리 데이터를 얻는 주기를 정의하며, pressure observer의 요청된 샘플링 주기와 다를 수 있습니다. 속도는 헤르츠(Hz) 단위로 측정됩니다.

pressure observer의 보고 주기데이터 수집 단계를 수행하는 주기를 의미하며, 이 값은 샘플링 주기를 초과하지 않습니다.

샘플링 주기요청된 샘플링 주기와 다를 수 있으며, 요청된 샘플링 주기가 하위 플랫폼 및 User Agent가 지원하거나 허용하는 범위를 벗어날 경우에 해당됩니다.

명세에서는 11.2.2 주기 난독화 조항에 따라 주기도 추가로 난독화합니다.

사용자가 샘플링 주기를 명시적으로 요청하지 않은 경우, 샘플링 주기구현 정의(implementation-defined)입니다.

참고

4. 플랫폼 프리미티브

프레셔 소스는 하드웨어 카운터 또는 기본 프레임워크에 대한 추상적이고 구현 정의 인터페이스로, 소스 타입에 대한 텔레메트리 데이터를 제공합니다. PressureSource에서 정의합니다. 프레셔 소스는 더 정확한 결과를 제공할 수 있는 경우 다른 소스의 데이터와 데이터 퓨전을 활용할 수 있습니다.

프레셔 소스가 제공하는 텔레메트리 데이터는 본 명세에서 프레셔 소스 샘플로 나타내며, 다음 항목으로 구성된 구조체입니다:

프레셔 소스최신 샘플을 가집니다. 이는 프레셔 소스 샘플 또는 null이며, 기본값은 null입니다.

플랫폼 콜렉터프레셔 소스로부터 텔레메트리 샘플을 획득하고, 이를 프레셔 상태로 변환하여 user agent에 제공하는 추상 인터페이스입니다.

플랫폼 콜렉터는 다음과 같은 연관 데이터를 가집니다:

프레셔 소스가 제공하고 최신 샘플data에 저장된 텔레메트리 데이터의 형식은 구현 정의이며, 플랫폼 콜렉터가 이를 프레셔 상태로 변환하는 과정 역시 구현 정의입니다.

본 명세의 목적상, 플랫폼 콜렉터글로벌 객체플랫폼 콜렉터 매핑으로 범위가 지정됩니다.

자동화 목적상, 플랫폼 콜렉터가상 프레셔 소스에 연결되고, 해당 data를 원시 플랫폼 데이터가 아닌, 프레셔 상태로서 사용할 수 있어야 하며, 이것을 조정된 프레셔 상태로 변환할 필요가 없습니다.

텔레메트리 데이터 수집은 일반적으로 하드웨어 카운터를 폴링하는 작업이기 때문에, 무료로 이루어지는 작업이 아니므로 관찰하는 사람이 없는 경우에는 발생해서는 안 됩니다. 자세한 내용은 10.5 수명 주기 및 가비지 컬렉션을 참고하십시오.

플랫폼 콜렉터는 특정 주기로 데이터를 샘플링합니다. user agent는(가능한 경우) 개인정보 보호를 위해 이 주기를 조정하거나, 특정 측정값을 무시·합칠 수 있습니다.

5. 사용자 알림

user agent가 프레셔 옵저버가 활성 상태임을 사용자에게 보여주고, 사용자가 진행 중인 동작을 차단하거나 단순히 알림을 닫을 수 있는 수단을 제공하는 등 어떤 형태로든 사용자 가시적 알림을 표시하는 것이 권장됩니다(RECOMMENDED).

6. 정책 제어

Compute Pressure API는 "compute-pressure" 토큰으로 식별되는 정책 제어 기능을 정의합니다. 기본 허용 목록(default allowlist)'self'입니다.

워커(dedicated 및 shared 워커)는 자신을 소유한 문서의 권한 정책을 따릅니다.

공유 워커(shared worker)는 여러 소유 문서를 가질 수 있으며, 동일 출처(same origin)의 다른 문서에서도 획득될 수 있습니다. 이 경우, 모든 소유 문서는 본 명세에서 정의하는 사용 허용(allowed to use)을 받아야 하며, 정책 제어 기능이 허용되어야 합니다.

전용 워커(dedicated worker)는 다른 워커에서 생성될 수 있으며, 이 경우 최초 소유 문서(또는 공유 워커의 경우 소유 문서들)의 권한 정책이 소유 체인 상위까지 적용됩니다.

참고
참고

7. 내부 슬롯 정의

글로벌 객체는 다음을 가집니다:

등록된 옵저버(registered observer)옵저버(observer)(PressureObserver 객체)로 구성됩니다.

user agent는 다음을 가집니다:

생성된 PressureObserver 객체는 다음 내부 슬롯을 가집니다:

주기 난독화(rate obfuscation) 완화책을 위해 생성된 PressureObserver 객체는 다음 내부 슬롯도 가집니다:

8. 프레셔 상태

프레셔 상태는 웹사이트가 계산 및 시스템 부담 변화에 반응하여 품질·서비스 또는 사용자 경험 저하를 최소화할 수 있는 최소 유용 상태 집합을 나타냅니다.

WebIDLenum PressureState { "nominal", "fair", "serious", "critical" };

PressureState 열거형은 다음과 같은 프레셔 상태를 나타냅니다:

참고

9. 기여 요소

기여 요소란 현재 프레셔 상태에 기여하는 기저 하드웨어 및 운영체제 메트릭을 의미하며, 구현 정의일 수 있습니다.

조정된 프레셔 상태소스 타입구현 정의 데이터 등을 입력 받아, 프레셔 상태를 결정하는 구현 정의 알고리즘이며, MUST 결정을 임의화(비결정적)해야 break calibration 완화책이 효과적입니다.

기여 요소 변화가 중대한 경우 단계는 아래와 같습니다:

  1. 현재 프레셔 상태에 기여하는 구현 정의 저수준 하드웨어 메트릭이 각 메트릭별 구현 정의 임계값을 하회 또는 상회하면 true를 반환합니다.
  2. false를 반환합니다.
참고

10. 프레셔 옵저버

Compute Pressure API는 개발자가 CPU와 같은 시스템 리소스의 압력(부하) 상태를 이해할 수 있도록 합니다.
WebIDLcallback PressureUpdateCallback = undefined (
  sequence<PressureRecord> changes,
  PressureObserver observer
);
이 콜백은 압력 상태가 변경될 때 호출됩니다.

10.2 PressureObserver 객체

PressureObserver압력 상태의 변화를 관찰하는 데 사용할 수 있습니다.

WebIDL[Exposed=(DedicatedWorker,SharedWorker,Window), SecureContext]
interface PressureObserver {
  constructor(PressureUpdateCallback callback);

  Promise<undefined> observe(PressureSource source, optional PressureObserverOptions options = {});
  undefined unobserve(PressureSource source);
  undefined disconnect();
  sequence<PressureRecord> takeRecords();

  [SameObject] static readonly attribute FrozenArray<PressureSource> knownSources;
};

PressureObserver 인터페이스는 PressureObserver를 나타냅니다.

10.2.1 constructor() 메서드

new PressureObserver(callback) 생성자의 단계는 다음과 같습니다:

  1. this.[[Callback]]callback으로 설정합니다.

10.2.2 observe() 메서드

observe(source, options) 메서드의 단계는 다음과 같습니다:

  1. relevantGlobalthis관련 글로벌 객체로 설정합니다.
  2. 각각document에 대해, relevantGlobal소유 문서 집합 안에서:
    1. document사용할 수 있는 정책 제어 기능 토큰 "compute-pressure"에 해당하지 않는다면, 거부된 프라미스NotAllowedError로 반환합니다.
    참고
  3. this[[SampleIntervalMap]][source] 를 optionssampleInterval로 설정합니다.
  4. promise새 프라미스로 설정합니다.
  5. pendingPromiseTuple을 (source, promise)로 설정합니다.
  6. 추가pendingPromiseTuplethis[[PendingObservePromises]]에 추가합니다.
  7. 프라미스가 완료되면 반응합니다:
  8. 다음 단계를 병렬로 실행합니다:
    1. platformCollector를 null로 설정합니다.
    2. relevantGlobal플랫폼 콜렉터 매핑포함하는 경우 source:
      1. platformCollectorrelevantGlobal플랫폼 콜렉터 매핑[source]으로 설정합니다.
    3. 그렇지 않다면:
      1. newCollector플랫폼 콜렉터의 새 인스턴스로 설정하고, 그 연결된 압력 소스는 null로 둡니다.
      2. virtualPressureSource가상 압력 소스를 가져오기의 결과로 설정합니다. 입력은 sourcerelevantGlobal입니다.
      3. virtualPressureSource가 null이 아니면:
        1. virtualPressureSource샘플 제공 가능이 true인 경우:
          1. newCollector연결된 압력 소스virtualPressureSource로 설정합니다.
          2. 추가newCollectorvirtualPressureSource연결된 플랫폼 콜렉터에 추가합니다.
      4. 그렇지 않다면:
        1. realPressureSource구현 정의압력 소스로 설정합니다. 이는 source에 대한 텔레메트리 데이터를 제공하며, 존재하지 않으면 null입니다.
        2. newCollector연결된 압력 소스realPressureSource로 설정합니다.
      5. newCollector연결된 압력 소스가 null이 아니면:
        1. platformCollectornewCollector로 설정합니다.
        2. relevantGlobal플랫폼 콜렉터 매핑[source]을 platformCollector로 설정합니다.
    4. platformCollector가 null이면, 글로벌 작업을 큐에 추가하여 PressureObserver 작업 소스relevantGlobal를 제공하고 promiseNotSupportedError로 거부한 뒤 이 단계를 중단합니다.
    5. 데이터 수집 활성화sourcerelevantGlobal로 호출합니다.
    6. 글로벌 작업을 큐에 추가하여 PressureObserver 작업 소스relevantGlobal를 제공하고 다음 단계를 실행합니다:
      1. promise가 거부된 경우, 다음 하위 단계를 실행합니다:
        1. relevantGlobal등록된 관찰자 목록source에 대해 비어 있다면, 데이터 수집 비활성화sourcerelevantGlobal로 호출합니다.
        2. 반환합니다.
      2. 추가로 새 등록된 관찰자를 추가하며 그 관찰자this입니다. 이를 relevantGlobal등록된 관찰자 목록source에 추가합니다.
      3. promise를 이행합니다.
  9. promise를 반환합니다.

10.2.3 unobserve() 메서드

unobserve(source) 메서드의 단계는 다음과 같습니다:

  1. source지원되는 소스 유형이 아니라면, "NotSupportedError"를 던집니다.
  2. 제거this[[QueuedRecords]]에서 recordssource와 연관된 모든 항목을 제거합니다.
  3. 제거this[[SampleIntervalMap]][source]를 제거합니다.
  4. 제거this[[LastRecordMap]][source]를 제거합니다.
  5. 제거this[[AfterPenaltyRecordMap]][source]를 제거합니다.
  6. 각각의 (promiseSource, pendingPromise)에 대해, this[[PendingObservePromises]]에서, sourcepromiseSource와 같다면 거부pendingPromiseAbortError로 거부합니다.
  7. relevantGlobalthis관련 글로벌 객체로 설정합니다.
  8. registeredObserverListrelevantGlobal등록된 관찰자 목록source에 대한 것으로 설정합니다.
  9. 제거등록된 관찰자 중에서 registeredObserverList에서 그 관찰자this인 항목을 제거합니다.
  10. registeredObserverList비어 있다면:
    1. 데이터 수집 비활성화sourcerelevantGlobal로 호출합니다.
    2. 제거relevantGlobal플랫폼 콜렉터 매핑[source]을 제거합니다.

10.2.4 disconnect() 메서드

disconnect() 메서드의 단계는 다음과 같습니다:

  1. 비우기observer[[QueuedRecords]]를 비웁니다.
  2. 비우기this[[SampleIntervalMap]]을 비웁니다.
  3. 비우기this[[LastRecordMap]]을 비웁니다.
  4. 비우기this[[AfterPenaltyRecordMap]]을 비웁니다.
  5. 각각의 (promiseSource, pendingPromise)에 대해, this[[PendingObservePromises]]에서 거부pendingPromiseAbortError로 거부합니다.
  6. relevantGlobalthis관련 글로벌 객체로 설정합니다.
  7. 각각sourceregisteredObserverList에 대해, relevantGlobal등록된 관찰자 목록 순서 있는 맵에서:
    1. 제거등록된 관찰자 중에서 registeredObserverList에서 그 관찰자this인 항목을 제거합니다.
    2. registeredObserverList비어 있다면:
      1. 데이터 수집 비활성화sourcerelevantGlobal로 호출합니다.
      2. 제거relevantGlobal플랫폼 콜렉터 매핑[source]을 제거합니다.

10.2.5 takeRecords() 메서드

참고

takeRecords() 메서드의 단계는 다음과 같습니다:

  1. records복제observer[[QueuedRecords]]의 복제로 설정합니다.
  2. 비우기observer[[QueuedRecords]]를 비웁니다.
  3. records를 반환합니다.

10.2.6 knownSources 속성

knownSources 게터의 단계는 다음과 같습니다:

  1. 사용자 에이전트지원되는 소스 유형을 알파벳 순서로 반환합니다.

참고

10.3 PressureRecord 인터페이스

WebIDL[Exposed=(DedicatedWorker,SharedWorker,Window), SecureContext]
interface PressureRecord {
  readonly attribute PressureSource source;
  readonly attribute PressureState state;
  readonly attribute DOMHighResTimeStamp time;
  [Default] object toJSON();
};

생성된 PressureRecord 객체는 다음 내부 슬롯을 가집니다:

10.3.1 source 속성

source 게터 단계는 그 [[Source]] 내부 슬롯을 반환하는 것입니다.

10.3.2 state 속성

state 게터 단계는 그 [[State]] 내부 슬롯을 반환하는 것입니다.

10.3.3 time 속성

time 게터 단계는 그 [[Time]] 내부 슬롯을 반환하는 것입니다.

10.3.4 toJSON 멤버

PressureRecord.toJSON이 호출되면, Web IDL Standard기본 toJSON 단계를 실행합니다.

10.4 PressureObserverOptions 딕셔너리

WebIDLdictionary PressureObserverOptions {
  [EnforceRange] unsigned long sampleInterval = 0;
};

10.4.1 sampleInterval 멤버

sampleInterval 멤버는 밀리초로 표현된 요청된 샘플링 간격을 나타냅니다. 값이 0으로 설정된 경우, 시스템은 PressureUpdateCallbackPressureState에 변화가 있을 때만 호출합니다.

참고

10.5 생명 주기와 가비지 컬렉션

글로벌 객체는 그들의 등록된 관찰자에 강한 참조를 가집니다. 이는 등록된 관찰자 목록 (소스별로 하나씩) 안에 있습니다.

참고

10.6 처리 모델

이 섹션은 사양을 구현할 때 사용자 에이전트가 수행해야 하는 단계를 설명합니다.

10.6.1 지원 알고리즘

observer 인수를 받아 관찰 창 재설정 단계를 다음과 같이 수행합니다:

관찰 창 재설정 단계를 실행하고 타이머를 시작하여, 관찰자의 [[ObservationWindow]] 시간이 경과하면 다른 랜덤 값으로 단계를 다시 실행하도록 합니다.

참고

관련 글로벌 객체 relevantGlobal에 대한 소유 문서 집합을 결정하려면:

  1. owningDocumentSet을 빈 집합으로 설정합니다.
  2. relevantGlobalWindow라면, 추가relevantGlobal연결된 문서owningDocumentSet에 추가합니다.
  3. 그렇지 않다면, 각각owner에 대해, WorkerGlobalScoperelevantGlobal소유자 집합 안에서:
    1. ownerDocument라면, 추가ownerowningDocumentSet에 추가합니다.
    2. ownerWorkerGlobalScope라면, owningDocumentSet합집합으로 설정하며, owningDocumentSetowner소유 문서 집합의 합집합입니다.
  4. owningDocumentSet를 반환합니다.

document 인수를 받아 문서에 암시적 포커스가 있음 단계를 다음과 같이 수행합니다:

  1. document완전히 활성 상태가 아니라면, false를 반환합니다.
  2. relevantGlobaldocument관련 글로벌 객체로 설정합니다.
  3. 각각origin에 대해, 활성 Picture-in-Picture 세션의 개시자 목록에서:
    1. relevantGlobal관련 설정 객체오리진origin동일 오리진이라면, true를 반환합니다.
  4. relevantGlobal브라우징 컨텍스트캡처 중이라면, true를 반환합니다.
  5. topLevelBCrelevantGlobal브라우징 컨텍스트최상위 브라우징 컨텍스트로 설정합니다.
  6. topLevelBC시스템 포커스를 가지지 않는다면, false를 반환합니다.
  7. focusedDocumenttopLevelBC 현재 포커스된 영역노드 문서로 설정합니다.
  8. relevantGlobal관련 설정 객체오리진focusedDocument오리진동일 오리진이라면, true를 반환합니다.
  9. 그렇지 않다면, false를 반환합니다.

observer 인수를 받아 데이터를 수신할 수 있음 단계를 다음과 같이 수행합니다:

  1. relevantGlobalobserver관련 글로벌 객체로 설정합니다.
  2. relevantGlobalWindow 객체인 경우:
    1. relevantGlobal연결된 문서문서에 암시적 포커스가 있음을 실행한 결과를 반환합니다.
  3. relevantGlobalWorkerGlobalScope 객체인 경우:
    1. owningDocumentsrelevantGlobal소유 문서 집합으로 설정합니다.
    2. 각각document에 대해, owningDocuments 안에서:
      1. 문서에 암시적 포커스가 있음document로 실행한 결과가 true라면, true를 반환합니다.
      2. 그렇지 않다면, 계속합니다.
  4. false를 반환합니다.
참고

observer, source, timestamp 인수를 받아 속도 테스트 통과 단계를 다음과 같이 수행합니다:
  1. observer[[LastRecordMap]][source]가 존재하지 않으면, true를 반환합니다.
  2. recordobserver[[LastRecordMap]][source]로 설정합니다.
  3. sampleIntervalobserver[[SampleIntervalMap]][source]로 설정합니다.
  4. timeDeltaMilliseconds = timestamp - record[[Time]]로 설정합니다.
  5. timeDeltaMillisecondssampleInterval이면 true를 반환하고, 그렇지 않으면 false를 반환합니다.
observer, source, state 인수를 받아 디스패치해야 함 단계를 다음과 같이 수행합니다:
  1. observer[[SampleIntervalMap]][source] > 0이면, true를 반환합니다.
  2. observer[[LastRecordMap]][source]가 존재하지 않으면, true를 반환합니다.
  3. recordobserver[[LastRecordMap]][source]로 설정합니다.
  4. record[[State]]state와 같지 않다면, true를 반환합니다.
  5. false를 반환합니다.
observer, source 인수를 받아 속도 난독화 테스트 통과 단계를 다음과 같이 수행합니다:
  1. observer의 [[ChangesCountMap]][source]를 증가시킵니다.
  2. observer의 [[ChangesCountMap]][source] ≤ observer의 [[MaxChangesThreshold]]를 반환합니다.

소스 유형 sourcerelevantGlobal을 받아 가상 압력 소스를 가져오기를 다음과 같이 수행합니다. 이는 가상 압력 소스 또는 null을 반환합니다.

  1. topLevelTraversable를 null로 설정합니다.
  2. relevantGlobalWindow 객체라면:
    1. topLevelTraversablerelevantGlobal내비게이션 가능 객체의 최상위 트래버서블로 설정합니다.
  3. relevantGlobalDedicatedWorkerGlobalScope 객체라면:
    1. owningDocumentsrelevantGlobal소유 문서 집합으로 설정합니다.
    2. owningDocuments비어 있다면, null을 반환합니다.
    3. 단언: owningDocuments크기는 1입니다.
    4. topLevelTraversableowningDocuments[0]의 노드 내비게이션 가능 객체의 최상위 트래버서블로 설정합니다.
  4. topLevelTraversable가 null이라면, null을 반환합니다.
  5. topLevelVirtualPressureSourceMappingtopLevelTraversable가상 압력 소스 매핑으로 설정합니다.
  6. virtualPressureSource를 null로 설정합니다.
  7. topLevelVirtualPressureSourceMapping포함하는 경우 source:
    1. virtualPressureSourcetopLevelVirtualPressureSourceMapping[source]로 설정합니다.
  8. virtualPressureSource를 반환합니다.

10.6.2 데이터 수집 및 전달

소스 유형 sourcerelevantGlobal을 받아 데이터 수집 활성화를 다음과 같이 수행합니다:

  1. relevantGlobal플랫폼 콜렉터 매핑포함하지 않으면 source, 이 단계를 중단합니다.
  2. platformCollectorrelevantGlobal플랫폼 콜렉터 매핑[source]으로 설정합니다.
  3. platformCollector활성화됨이 true라면, 이 단계를 중단합니다.
  4. platformCollector활성화됨을 true로 설정합니다.
  5. 구현 정의된 방식으로, 데이터 수집 단계를 relevantGlobal, source, platformCollector와 함께 시작합니다.
    참고

소스 유형 sourcerelevantGlobal을 받아 데이터 수집 비활성화를 다음과 같이 수행합니다:

  1. relevantGlobal플랫폼 콜렉터 매핑포함하지 않으면 source, 이 단계를 중단합니다.
  2. platformCollectorrelevantGlobal플랫폼 콜렉터 매핑[source]으로 설정합니다.
  3. platformCollector활성화됨이 false라면, 이 단계를 중단합니다.
  4. 구현 정의된 방식으로, 데이터 수집 단계를 relevantGlobal, source, platformCollector에 대해 중지합니다.
  5. platformCollector활성화됨을 false로 설정합니다.
  6. platformCollector연결된 압력 소스가상 압력 소스인 경우:
    1. 제거platformCollector를 그 연결된 압력 소스연결된 플랫폼 콜렉터에서 제거합니다.
  7. 그렇지 않다면, 구현 정의된 단계를 수행하여 platformCollector연결된 압력 소스에게 텔레메트리 데이터 가져오기를 중지하도록 신호를 보냅니다.

relevantGlobal, source, platformCollector를 받아 데이터 수집 단계를 다음과 같이 수행합니다:

  1. pressureSourceplatformCollector연결된 압력 소스로 설정합니다.
  2. pressureSource가 null이면, 이 단계를 중단합니다.
  3. samplepressureSource최신 샘플로 설정합니다.
  4. sample이 null이면, 이 단계를 중단합니다.
  5. state를 null로 설정합니다.
  6. pressureSource가상 압력 소스인 경우:
    1. statesample데이터에 저장된 PressureState로 설정합니다.
  7. 그렇지 않다면:
    1. 기여 요인의 변화가 상당함이 false라면, 이 단계를 중단합니다.
    2. state조정된 압력 상태로 설정합니다. 이는 sourcesample데이터로부터 계산됩니다.
      참고
  8. 단언: state는 null이 아닙니다.
  9. rawTimestampsample타임스탬프로 설정합니다.
  10. timeValue상대 고해상도 시간으로 설정합니다. 이는 rawTimestamprelevantGlobal를 기준으로 합니다.
  11. 각각observer에 대해, relevantGlobal등록된 관찰자 목록source에 대해:
    1. 데이터를 수신할 수 있음observer로 실행한 결과가 false라면, 계속합니다.
    2. 속도 테스트 통과observer, source, timeValue로 실행한 결과가 false라면, 계속합니다.
    3. 디스패치해야 함observer, source, state로 실행한 결과가 false라면, 계속합니다.
    4. record를 새 PressureRecord 객체로 설정하며, 그 [[Source]]source, [[State]]state, [[Time]]timeValue로 설정합니다.
    5. observer[[AfterPenaltyRecordMap]][source]가 존재한다면:
      1. observer[[AfterPenaltyRecordMap]][source]를 record로 설정합니다.
      2. 계속합니다.
    6. 속도 난독화 테스트 통과observer, source로 실행한 결과가 false라면:
      1. observer[[AfterPenaltyRecordMap]][source]를 record로 설정합니다.
      2. observer[[ChangesCountMap]][source]를 0으로 설정합니다.
      3. observer[[PenaltyDuration]] 기간의 타이머를 생성하고 다음 콜백을 설정합니다:
        1. observer[[AfterPenaltyRecordMap]][source]가 존재한다면:
          1. recordobserver[[AfterPenaltyRecordMap]][source]로 설정합니다.
          2. 제거observer[[AfterPenaltyRecordMap]][source]를 제거합니다.
          3. 레코드 큐에 추가observer, source, record로 실행합니다.
      4. 계속합니다.
    7. 레코드 큐에 추가observer, source, record로 실행합니다.

10.6.3 PressureRecord 큐에 추가

observer, source, record 인수를 받아 레코드 큐에 추가를 다음과 같이 실행합니다:

  1. observer[[QueuedRecords]]크기최대 큐 대기 레코드 수보다 크다면, 제거로 첫 번째 항목을 제거합니다.
  2. 추가recordobserver[[QueuedRecords]]에 추가합니다.
  3. observer[[LastRecordMap]][source]를 record로 설정합니다.
  4. PressureObserver 작업 큐에 추가observer관련 글로벌 객체로 실행합니다.

10.6.4 Pressure Observer 작업 큐에 추가

PressureObserver 작업 소스는 작업을 예약하여 10.6.5 Pressure Observer에 알림을 수행하는 데 사용되는 작업 소스입니다.

relevantGlobal을 입력으로 받아 Pressure Observer 작업 큐에 추가를 다음과 같이 실행합니다:

  1. relevantGlobalPressure Observer 작업 대기됨이 true라면, 반환합니다.
  2. relevantGlobalPressure Observer 작업 대기됨을 true로 설정합니다.
  3. 글로벌 작업을 큐에 추가하여 PressureObserver 작업 소스relevantGlobal를 제공하고 Pressure Observer에 알림을 수행합니다.

10.6.5 Pressure Observer에 알림

relevantGlobal을 입력으로 받아 Pressure Observer에 알림을 다음과 같이 실행합니다:

  1. relevantGlobalPressure Observer 작업 대기됨을 false로 설정합니다.
  2. notifySet을 새로운 집합으로 설정하고, 이는 relevantGlobal의 모든 관찰자를 포함합니다. 이들은 relevantGlobal등록된 관찰자 목록에 포함되어 있습니다.
  3. 각각observer에 대해, notifySet 안에서:
    1. records복제observer[[QueuedRecords]]의 복제로 설정합니다.
    2. 비우기observer[[QueuedRecords]]를 비웁니다.
    3. records비어 있지 않다면, 호출observer[[Callback]]을 호출합니다. 인수는 « records, observer »이며 "report"로 호출합니다.

10.6.6 완전히 활성 상태 변경 처리

이 사양은 다음 문서 언로드 정리 단계를 정의합니다. Document document에 대해:

  1. relevantGlobaldocument관련 글로벌 객체로 설정합니다.
  2. 각각source 에 대해, relevantGlobal등록된 관찰자 목록 순서 있는 맵에서:
    1. 데이터 수집 비활성화sourcerelevantGlobal로 호출합니다.
    2. 제거relevantGlobal플랫폼 콜렉터 매핑[source]을 제거합니다.
이슈 275: bfcache 통합 전략을 올바르게 결정하기

이 사양은 이전에 Document가 다시 완전히 활성 상태가 되는 경우(즉, Document재활성화 단계와의 통합)와 관련된 단계를 포함했습니다. 해당 단계는 의도된 동작에 대해 논의하는 동안 제거되었습니다.

10.6.7 워커 상태 변경 처리

참고

WorkerGlobalScope relevantGlobal종료 중 플래그가 true로 설정될 때마다, 다음 단계를 수행합니다:

  1. 각각source 에 대해, relevantGlobal등록된 관찰자 목록 순서 있는 맵에서:
    1. 데이터 수집 비활성화sourcerelevantGlobal로 호출합니다.
    2. 제거relevantGlobal플랫폼 콜렉터 매핑[source]을 제거합니다.

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

11.1 개인정보 보호 및 보안 위협의 유형

참고
작업 그룹은 이 섹션에서 이론적 및 실제로 알려진 모든 공격 벡터를 나열할 것입니다.

11.1.1 타이밍 공격

동일 same origin이 아닌 사이트들에서, 출처를 공유하지 않는 사이트들이 동시에 고유하거나 매우 정밀한 값을 접근할 수 있다면 사용자를 식별할 가능성이 있습니다. 이 공격은 11.2.1 데이터 최소화, 11.2.2 속도 난독화, 그리고 11.2.7 동일 오리진 제한으로 완화됩니다.

11.1.2 크로스 사이트 은닉 채널

컴퓨터 보안에서 은닉 채널(covert channel)은 원래 통신이 허용되지 않은 프로세스 간에 정보를 전송할 수 있는 능력을 만들어냅니다. 현대의 다중 프로세스 웹 엔진에서는 일반적으로 각 창이나 탭이 자체 프로세스에서 동작합니다 (문서가 same origin이거나 same site인 경우 보통 동일한 프로세스를 공유). 이 API를 사용하면 탭 A의 사이트가 CPU 상태를 조작한 뒤 채널 C로 먼저 브로드캐스트하고, 이어서 다른 탭의 사이트 B(사이트 A와 same site가 아님)가 이 API를 사용해 채널 C에서 브로드캐스트된 데이터를 읽어 CPU 상태 변경 시점을 알아내는 식으로, 크로스 사이트 은닉 채널 C를 만들 수 있습니다. 이 과정은 사이트 A와 B 모두에서 스크립트가 실행되는 한 반복될 수 있습니다.

이 공격은 11.2.2 속도 난독화11.2.5 보정 방해로 완화됩니다. 구현자들은 장시간 실행되는 스크립트에 대해 이러한 모든 완화를 고려하는 것이 권장됩니다.

참고
스크립트가 오래 실행될수록 제안된 크로스 사이트 은닉 채널을 통해 더 많은 정보를 전송할 수 있습니다. 예를 들어, 사용자가 화상 회의 사이트와 또 다른 장시간 실행되는 사이트를 동시에 사용하는 경우, 일반적인 브라우징 시나리오에 비해 더 많은 정보가 전송될 수 있습니다. 반면, 화상 회의 세션과 같은 워크로드는 보통 CPU에 지속적인 압력을 가해 예측 가능한 방식으로 압력 상태를 조작하기 더 어렵게 만듭니다.

11.1.3 표적 익명성 해제 공격

표적 익명성 해제 공격은 사용자의 익명성을 위협하는 중대한 위협 범주에 해당합니다. 이러한 공격은 악의적이거나 일부가 손상된 웹사이트(“악성 사이트”)가 방문자가 이메일 주소나 소셜 미디어 핸들 같은 특정 공개 식별자를 보유하고 있는지를 파악할 수 있게 합니다.

익명성은 일부에게 사치일 수 있으나, 어떤 이들에게는 생존과 직결된 문제입니다. 예컨대 정치적 시위에 참여하거나 민감한 주제를 다루는 기자 등은 그 사례가 될 수 있습니다.

예를 들어, 공격자는 공개 리소스 공유 서비스(“피해자 사이트”)를 이용해 대상에게 비공개로 리소스를 공유하고, 사이드 채널을 통해 리소스를 로드할 때의 부수 효과(성공적인 접근을 나타냄)를 측정할 수 있습니다. 로그인된 방문자가 포함된 리소스에 성공적으로 접근할 수 있다면, 현재 방문이 실제로 의도된 대상임을 나타냅니다.

구체적으로, 전체 CPU 압력에 대한 신뢰할 수 있는 정보를 노출하면 교차 출처 탐색의 대상(예: 다른 사이트의 iframe 또는 팝업 창)이 CPU 집약적 작업을 수행했는지 공격 사이트가 파악할 수 있습니다.

pop-undertab-under 같은 기법을 사용해 사용자로부터 로딩을 숨길 수 있습니다.

가능한 한 가지 공격은 악성 웹사이트가 사용자가 로그인한 피해자 사이트의 리소스(예: 동영상 스트리밍 사이트나 온라인 문서 편집기)를 가리키는 팝업을 열고, 특정 사용자들과 공유된 리소스를 대상으로 하는 것입니다.

리소스를 로드하면 CPU에 가해지는 압력이 증가한다고 가정할 때, 이는 사이드 채널을 형성하여 사용자가 해당 리소스에 접근 권한이 있는 계정으로 로그인했는지 공격 사이트에 드러내어 사용자의 익명성을 해제할 수 있습니다.

최신 CPU가 높은 압력 상태에서 빠르게 회복된다는 점을 고려하면, 가능한 완화 전략 중 하나로 팝업 및 iframe 콘텐츠 로드 직후 몇 초 동안 판독을 일시적으로 비활성화하는 방법이 있을 수 있습니다.

11.2 완화 전략

참고
이 섹션은 본 사양에 적용 가능한 완화 전략을 높은 수준에서 설명합니다. 이러한 완화의 규범적 정의는 본 사양의 해당 알고리즘에 통합되어 있습니다. 구현자들은 본 사양에서 정의된 완화를 구현할 때 TAG의 시크릿 모드(사생활 보호 모드) 가이드를 고려하는 것이 권장됩니다.

11.2.1 데이터 최소화

본 사양은 기본 플랫폼의 저수준 세부사항과 관련된 데이터 노출을 높은 가치의 사용 사례를 해결하는 데 필요한 최소한으로 제한하기 위해 일반적인 데이터 최소화 원칙을 따릅니다. 여기에는 디바이스 식별 정보의 노출 제한에 대한 고려도 포함됩니다.

본 사양의 맥락에서 데이터 최소화 원칙의 구체적 적용은 11.2.2 속도 난독화11.2.7 동일 오리진 제한에서 논의됩니다.

11.2.2 속도 난독화

본 사양은 rate obfuscation 완화를 구현하도록 요구합니다. 이는 구현 정의의 슬라이딩 관찰 창 동안 압력 변화 횟수를 추적하고, 압력 변화 횟수가 구현 정의 임계를 초과하는 경우 플래그를 설정합니다. 마찬가지로, 여러 상태에 걸친 높은 압력 상태 변화 횟수와 같은 비정상 활동을 관찰하고 동일하게 플래그를 설정하는 것도 구현에 권장됩니다.

이 플래그가 설정되면, 구현은 압력 관찰자에 대해 페널티를 부여하여 평소처럼 스크립트에 압력 상태 변화를 알릴 수 없도록 하는 것이 권장됩니다. 페널티 기간은 구현 정의이며 무작위화하는 것이 권장됩니다. 페널티 이후 압력 관찰자에게 알림이 다시 동작을 재개할 때에는, 플랫폼 콜렉터로부터 페널티 동안 수신된 중간 상태 정보는 무시하고 최신 압력 상태만 보고합니다.

11.2.3 속도 난독화의 규범적 매개변수

구현 경험에 근거하여, 구현자들은 다음을 사용해야 합니다:

참고

11.2.4 속도 난독화의 비규범적 매개변수

이 절은 비규범적입니다.

구현 경험에 근거하여, 구현자들은 다음을 사용하는 것이 권장됩니다:

  • PressureObserver의 [[ObservationWindow]] 내부 슬롯은 300000밀리초(5분)~600000밀리초(10분) 범위.
참고

11.2.5 보정 방해

보정(calibration) 과정에서 공격자는 CPU를 조작하여 이 API가 조작된 워크로드가 가하는 압력에 반응해 특정 압력 상태로 전이했다고 보고할 확률을 최대화하려고 시도합니다. 이 break calibration 완화는 런타임에 이러한 압력 상태 전이에 기여하는 구현 정의 저수준 하드웨어 지표를 약간 변경함으로써 이 보정 과정을 지연시키거나 실패하게 만들 수 있습니다. 초기 보정이 성공하더라도, 이 완화가 지속적으로 동작하는 동안 런타임에서 그 결과는 무효화됩니다. 재보정 시도 역시 유사하게 완화됩니다.

참고

11.2.6 보정 방해 매개변수

이 절은 비규범적입니다.

구현 경험에 근거하여, 구현자들은 120000밀리초(2분)에서 240000밀리초(4분) 사이의 범위에서 무작위화된 시간 값으로 완화를 적용하는 것이 권장됩니다.

참고

11.2.7 동일 오리진 제한

기본적으로 데이터 전달은 initiator of an active picture-in-picture-session과 동일 오리진에서 제공되는 문서, capturing 중인 문서, 또는(있다면) system focus를 가진 문서로 제한됩니다.

위 규칙에 따라 데이터 전달 자격을 갖춘 문서는 child navigables의 문서에 이를 위임할 수 있습니다.

이 기능은 오직 선언된 정책을 통해서만 iframe 등의 서드파티 컨텍스트로 확장될 수 있습니다.

공유 워커는 최상위 문서와 연관된 iframe 등 여러 문서 간에 공유될 수 있습니다. owner set에 속한 문서 중 하나라도 위 데이터 전달 요건을 통과한다면, 공유 워커는 데이터 전달 자격을 갖추게 됩니다. 이는 포함된 iframe이 데이터를 상위(임베딩) 문서로 전달할 수 있음을 의미합니다.

12. 접근성 고려사항

The Compute Pressure API는 사용자 경험 개선에 중점을 둡니다. 이 API를 기반으로 구축된 애플리케이션이 접근성에 긍정적인 영향을 미칠 수 있는 방법은 두 가지가 있습니다.

  1. API를 사용해 수집된 정보를 바탕으로 결정을 내릴 때 사용자의 접근 필요를 고려하는 것.
  2. API에서 얻은 정보를 바탕으로 접근성을 염두에 두고 사용자 인터페이스를 설계하고 제작하는 것.

API 소비자로서 이 두 가지 기회를 모두 고려하는 것이 중요합니다. 다음은 몇 가지 예입니다:

13. 자동화

The Compute Pressure API는 테스트 작성자에게 도전 과제를 제시합니다. 인터페이스를 완전히 실행하려면 예측 가능한 방식으로 반응하는 물리적 하드웨어 장치가 필요하기 때문입니다.

이 문제를 해결하기 위해 이 문서는 [WEBDRIVER2] extension commands를 정의하여 실제 장치처럼 동작하고 특정 속성을 가질 수 있으며 그 측정값을 전적으로 사용자가 정의할 수 있는 가상 압력 소스들을 정의하고 제어할 수 있게 합니다.

13.1 가상 압력 소스

A 가상 압력 소스압력 소스로서 제어된 방식으로 실제 장치의 동작을 시뮬레이션합니다. 이 소스는 연결된 0개 이상의 플랫폼 수집기들에게 압력 변화를 보고합니다.

그러나 실제 압력 소스와 달리, 가상 압력 소스는 플랫폼 수집기가 압력 상태로 처리해야 하는 implementation-defined 값 대신에 압력 상태 값을 직접 보고합니다. 다시 말해, 가상 압력 소스의 압력 소스 샘플데이터PressureState입니다.

모든 압력 소스와 관련된 데이터(예: 압력 소스 샘플) 외에도, 각 가상 압력 소스는 다음을 가집니다:

최상위 트래버서블가상 압력 소스 매핑을 가지며, 이는 정렬된 맵으로 소스 타입들을 가상 압력 소스에 매핑합니다.

Note
Note

13.1.1 확장 명령

13.1.1.1 가상 압력 소스 생성
HTTP Method URI Template
POST /session/{session id}/pressuresource

extension command는 지정된 가상 압력 소스를 생성합니다. 동일한 소스 타입observe() 호출은 이 가상 압력 소스가 그들의 백업 압력 소스로 사용되게 하며, 이는 13.1.1.2 Delete virtual pressure source가 실행될 때까지 지속됩니다.

Properties of the parameters argument used by this algorithm
Parameter name Value type Required
type String yes
supported Boolean no

주어진 session, URL variablesparameters에 대한 원격 엔드 단계는 다음과 같습니다:

  1. virtualPressureSourceTypeget a property "type"을 parameters에서 호출한 결과로 둡니다.
  2. 만약 user agentsupported source typesvirtualPressureSourceType포함하지 않으면, errorWebDriver error code invalid argument와 함께 반환합니다.
  3. topLevelTraversablecurrent browsing contexttop-level traversable로 둡니다.
  4. topLevelVirtualPressureSourceMappingtopLevelTraversable가상 압력 소스 매핑으로 둡니다.
  5. 만약 topLevelVirtualPressureSourceMappingvirtualPressureSourceType을 포함하고 있다면, errorWebDriver error code invalid argument와 함께 반환합니다.
  6. supportedget a property with default로부터 "supported"와 true를 사용해 호출한 결과로 둡니다.
  7. virtualPressureSource를 새로운 가상 압력 소스로 둡니다.
  8. virtualPressureSource샘플을 제공할 수 있음supported로 설정합니다.
  9. topLevelVirtualPressureSourceMapping[virtualPressureSourceType]을 virtualPressureSource로 설정합니다.
  10. success를 데이터 null과 함께 반환합니다.
13.1.1.2 가상 압력 소스 삭제
HTTP Method URI Template
DELETE /session/{session id}/pressuresource/{type}

extension command는 주어진 가상 압력 소스를 삭제합니다. 이는 해당 소스 타입에 대한 데이터가 가능하다면 비가상 방식으로(기존 방식으로) 전달된다는 것을 의미합니다.

주어진 session, URL variablesparameters에 대한 원격 엔드 단계는 다음과 같습니다:

  1. virtualPressureSourceTypeURL variables["type"]의 값으로 둡니다.
  2. 만약 user agentsupported source typesvirtualPressureSourceType포함하지 않으면, errorWebDriver error code invalid argument와 함께 반환합니다.
  3. topLevelTraversablecurrent browsing contexttop-level traversable로 둡니다.
  4. topLevelVirtualPressureSourceMappingtopLevelTraversable가상 압력 소스 매핑으로 둡니다.
  5. pressureSourcetopLevelVirtualPressureSourceMapping[virtualPressureSourceType]로 둡니다.
  6. pressureSource연결된 플랫폼 수집기platformCollector에 대해:
    1. platformCollector연관된 압력 소스를 null로 설정합니다.
  7. Remove topLevelVirtualPressureSourceMapping[virtualPressureSourceType]을 수행합니다.
  8. success를 데이터 null과 함께 반환합니다.
13.1.1.3 가상 압력 소스 업데이트
HTTP Method URI Template
POST /session/{session id}/pressuresource/{type}

extension command는 새로운 압력 소스 샘플을 푸시하여 가상 압력 소스의 상태를 업데이트할 수 있게 합니다.

Note
Properties of the parameters argument used by this algorithm
Parameter name Value type Required
sample PressureState yes

주어진 session, URL variablesparameters에 대한 원격 엔드 단계는 다음과 같습니다:

  1. virtualPressureSourceTypeURL variables["type"]의 값으로 둡니다.
  2. 만약 user agentsupported source typesvirtualPressureSourceType포함하지 않으면, errorWebDriver error code invalid argument와 함께 반환합니다.
  3. topLevelTraversablecurrent browsing contexttop-level traversable로 둡니다.
  4. topLevelVirtualPressureSourceMappingtopLevelTraversable가상 압력 소스 매핑으로 둡니다.
  5. 만약 topLevelVirtualPressureSourceMappingvirtualPressureSource포함하지 않으면, errorWebDriver error codeunsupported operation와 함께 반환합니다.
  6. virtualPressureSourcetopLevelVirtualPressureSourceMapping[virtualPressureSourceType]로 둡니다.
  7. sampleget a property "sample"을 parameters에서 호출한 결과로 둡니다.
  8. 만약 samplePressureState 타입이 아니면, errorWebDriver error code invalid argument와 함께 반환합니다.
  9. virtualPressureSource최신 샘플을 새 압력 소스 샘플로 설정하며, 그 데이터 이고 타임스탬프unsafe shared current time입니다.
  10. 구현 방식에 따라, virtualPressureSource최신 샘플virtualPressureSource연결된 플랫폼 수집기들에게 이용 가능하게 만듭니다.
  11. success를 데이터 null과 함께 반환합니다.

14. 예제

이 섹션은 비규범적입니다.

예제 2: 콜백에서 옵저버에 접근하는 방법
const samples = [];

function pressureChange(records, observer) {
  for (const record of records) {
    samples.push(record.state);

    // We only want 20 samples.
    if (samples.length == 20) {
      observer.disconnect();
      return;
    }
  }
}

const observer = new PressureObserver(pressureChange);
observer.observe("cpu");

다음 예제에서는 압력이 critical 상태가 되면 동시 비디오 스트림 수를 줄이려고 합니다. 단순성을 위해 이 하나의 상태만 고려합니다.

스트림 수를 줄인다고 해서 반드시 critical 상태에서 벗어나거나 즉시 벗어나는 것은 아닐 수 있으므로, critical 상태에 있는 동안에는 30초마다 한 번씩씩 스트림을 하나씩 줄이는 전략을 사용합니다.

이를 위해 콜백이 실제로 상태가 변경될 때 또는 적어도 30초에 한 번 이상 호출되도록 보장합니다. 상태가 변경되면 인터벌 타이머를 재설정합니다.

예제 3: CPU 압력에 따라 비디오 피드 수를 조정하는 방법
let timerId = -1;
function pressureChange(records) {
  // Clear timer every time we are called, either by an actual state change,
  // or when called by setTimeout (see below).
  if (timerId > 0) {
    clearTimeout(timerId);
  }

  // When entering critical state, we want to recheck every 30sec if we are
  // still in critical state and if so, further reduce our concurrent streams.
  // For this reason we create a timer for 30 seconds that will call us back
  // with the last result in there were no change.
  const lastRecordArray = [records.at(records.length - 1)];
  timerId = setTimeout(pressureChange.bind(this, lastRecordArray), 30_000);

  for (const record of records) {
    if (record.state == "critical") {
      let streamsCount = getStreamsCount();
      setStreamsCount(streamsCount--);
    }
  }
}

const observer = new PressureObserver(pressureChange);
observer.observe("cpu");

다음 예제에서는 takeRecords() 의 사용법을 보여주고자 하며, 콜백이 마지막으로 호출된 이후 누적된 남은 records를 가져옵니다.

이것은 disconnect()를 호출하기 전에 하는 것이 권장됩니다. 그렇지 않으면 disconnect()가 이들 레코드를 지우고 영구히 손실됩니다.

예를 들어, 벤치마크 워크로드 동안 압력을 측정하고자 하여 워크로드의 정확한 기간 동안의 압력 텔레메트리를 원할 수 있습니다. 이는 작업이 완료되면 즉시 모든 옵저버를 disconnect하고, 이벤트 루프 사이클의 일부로 아직 전달되지 않았을 수 있는 보류 중인 압력 텔레메트리를 수동으로 요청하는 것을 의미합니다.

예제 4: disconnect 직전까지 모든 상태 변화를 처리하는 방법
function logWorkloadStatistics(records) {
  // do something with records.
}

const observer = new PressureObserver(logWorkloadStatistics);
observer.observe("cpu");

// Read pending state change records, otherwise they will be cleared
// when we disconnect.
const records = observer.takeRecords();
logWorkloadStatistics(records);

observer.disconnect();

다음 예제에서는 source를 인수로 하여 unobserve()를 호출함으로써 옵저버에게 특정 소스의 관찰을 중지하도록 지시하는 방법을 보여줍니다.

Note
예제 5: 특정 소스의 상태 변화 관찰을 중지하도록 옵저버에 알리는 방법
const observer = new PressureObserver(records => { /* do something with records. */ });

observer.observe("cpu");
observer.observe("gpu");

// Callback now gets called whenever the pressure state changes for 'cpu' or 'gpu'.

observer.unobserve("gpu");

// Callback now only gets called whenever the pressure state changes for 'cpu'.

다음 예제에서는 disconnect()를 호출하여 옵저버가 모든 상태 변화를 더 이상 관찰하지 않도록 하는 방법을 보여줍니다. disconnect()를 호출하면 이전의 모든 observe() 호출로 관찰하던 모든 소스에 대한 관찰이 중지됩니다.

또한 마지막 콜백이 호출된 이후 수집된 모든 보류 중인 레코드를 지웁니다.

예제 6: 옵저버에게 모든 상태 변화 관찰을 중지하도록 알리는 방법
const observer = new PressureObserver(records => { // do something with records. });
observer.observe("cpu");
observer.observe("gpu");

// some time later...

observer.disconnect();

// records will be an empty array, because of the previous disconnect().
const records = observer.takeRecords();

15. 적합성

비규범적(Non-normative)으로 표시된 섹션들뿐만 아니라, 이 사양의 모든 작성 가이드라인, 다이어그램, 예제 및 주석은 비규범적입니다. 이 사양의 나머지 모든 부분은 규범적(normative)입니다.

문서에서 핵심 단어인 MAY, MUST, 및 RECOMMENDED는 모두 대문자로 나타나는 경우에 한해 BCP 14 [RFC2119] [RFC8174]에 설명된 대로 해석됩니다.

이 사양은 하나의 제품에 대한 적합성 기준을 정의합니다: 이 사양에 포함된 인터페이스들을 구현하는 사용자 에이전트.

A. 감사의 글

이 섹션은 비규범적입니다.

다음 분들의 소중한 피드백과 조언에 깊이 감사드립니다: Anssi Kostiainen, Asaf Yaffe, Benjamin VanderSloot, Chen Xing, Evan Shrubsole, Florian Scholz, François Beaufort, Jan Gora, Jesse Barnes, Joshua Bell, Kamila Hasanbega, Matt Menke, Moh Haghighat, Nicolás Peña Moreno, Opal Voravootivat, Paul Jensen, Peter Djeu, Reilly Grant, Ulan Degenbaev, Victor Miura, Wei Wang, 그리고 Zhenyao Mo

개인 정보 검토, 피드백 및 제안된 교차 사이트 은밀 채널 공격과 그 완화책에 대해 W3C Privacy Interest Group (PING)과 특히 Peter Snyder에게 감사드립니다. 유사하게, 개인 브라우징의 프라이버시 및 이 사양에 대한 관련 기여에 대해 Ehsan Toreini에게도 감사드립니다.

Zoom 엔지니어링 팀의 Amanda Zhao, Fidel Tian, Zhiliang Wang 및 다른 분들께도 실무적 실험과 피드백으로 이 API가 실제 시나리오에서 개선되는 데 도움을 주신 점 특별히 감사드립니다.

B. 중대한 변경사항 요약

이 섹션은 비규범적입니다.

B.1 First Public Working Draft (2022/12/20) 이후 변경사항

B.2 색인

B.2.1 이 사양에서 정의된 용어

B.2.2 참조로 정의된 용어

  • [DOM] 는 다음을 정의합니다:
    • Document 인터페이스
    • 문서들
    • 노드
    • 노드 문서 ( Node 용)
  • [ECMASCRIPT] 는 다음을 정의합니다:
    • 에이전트 ( ECMAScript 용)
    • globalThis 속성 ( globalThis 용)
  • [HR-TIME] 는 다음을 정의합니다:
    • DOMHighResTimeStamp
    • 상대 고해상도 시간
    • unsafe current time (모노토닉 시계용)
    • unsafe shared current time
  • [HTML] 는 다음을 정의합니다:
    • 사용 허용(allowed to use)
    • 연관 문서(associated document)
    • 브라우징 컨텍스트
    • 자식 네비게이블 (child navigables)
    • 종료(closing) ( WorkerGlobalScope 용)
    • DedicatedWorkerGlobalScope 인터페이스
    • 완전 활성(fully active) ( Document 용)
    • 글로벌 객체
    • iframe 요소
    • 병렬(in parallel)
    • 네비게이블(navigable) ( Window 용)
    • 노드 네비게이블(node navigable)
    • 출처(origin)
    • 소유자 집합(owner set) ( WorkerGlobalScope 용)
    • 정책 컨테이너(policy container) ( WorkerGlobalScope 용)
    • 글로벌 태스크 큐(queue a global task)
    • 재활성화(reactivate) ( Document 용)
    • 관련 글로벌 객체(relevant global object)
    • 시간 기원(time origin) (환경 설정 객체용)
    • 최상위 브라우징 컨텍스트
    • 최상위 트래버서블
    • 최상위 트래버서블 (브라우징 컨텍스트용)
    • 언로딩 문서 정리 단계
    • Window 인터페이스
    • WorkerGlobalScope 인터페이스
  • [INFRA] 는 다음을 정의합니다:
    • Append (리스트용)
    • Append (집합(set)용)
    • Assert
    • Clear (맵(map)용)
    • clone (리스트용)
    • contain (리스트용)
    • contains (맵용)
    • continue (반복용)
    • empty (리스트용)
    • For each (리스트용)
    • For each (맵용)
    • implementation-defined
    • item (리스트용)
    • items (구조체용)
    • keyed (맵용)
    • list
    • ordered map
    • queue
    • Remove (리스트용)
    • Remove (맵용)
    • set
    • size (리스트용)
    • struct
    • tuples
    • union (집합용)
    • value (맵용)
  • [MEDIACAPTURE-STREAMS] 는 다음을 정의합니다:
    • context is capturing
  • [PERMISSIONS-POLICY] 는 다음을 정의합니다:
    • default allowlist (정책 제어 기능용)
    • policy-controlled feature
  • [WEBDRIVER2] 는 다음을 정의합니다:
    • current browsing context
    • error
    • error code
    • extension command URI Template
    • extension commands
    • get a property
    • get a property with default
    • invalid argument
    • remote end steps
    • success
    • unsupported operation
  • [WEBIDL] 는 다음을 정의합니다:
    • a new promise
    • a promise rejected with
    • AbortError 예외
    • [Default] 확장 속성
    • default toJSON steps
    • [EnforceRange] 확장 속성
    • [Exposed] 확장 속성
    • FrozenArray 인터페이스
    • getter steps
    • invoke
    • NotAllowedError 예외
    • NotSupportedError 예외
    • object 타입
    • Promise 인터페이스
    • React ( promise 용)
    • rejected
    • resolved
    • [SameObject] 확장 속성
    • [SecureContext] 확장 속성
    • sequence
    • this
    • TypeError 예외
    • undefined 타입
    • unsigned long 타입

B.3 IDL 색인

WebIDLenum PressureSource { "cpu" };

enum PressureState { "nominal", "fair", "serious", "critical" };

callback PressureUpdateCallback = undefined (
  sequence<PressureRecord> changes,
  PressureObserver observer
);

[Exposed=(DedicatedWorker,SharedWorker,Window), SecureContext]
interface PressureObserver {
  constructor(PressureUpdateCallback callback);

  Promise<undefined> observe(PressureSource source, optional PressureObserverOptions options = {});
  undefined unobserve(PressureSource source);
  undefined disconnect();
  sequence<PressureRecord> takeRecords();

  [SameObject] static readonly attribute FrozenArray<PressureSource> knownSources;
};

[Exposed=(DedicatedWorker,SharedWorker,Window), SecureContext]
interface PressureRecord {
  readonly attribute PressureSource source;
  readonly attribute PressureState state;
  readonly attribute DOMHighResTimeStamp time;
  [Default] object toJSON();
};

dictionary PressureObserverOptions {
  [EnforceRange] unsigned long sampleInterval = 0;
};

C. 참조

C.1 규범적 참조

[dom]
DOM 표준. Anne van Kesteren. WHATWG. Living Standard. URL: https://dom.spec.whatwg.org/
[hr-time]
고해상도 시간. Yoav Weiss. W3C. 2024년 11월 7일. W3C 작업 초안. URL: https://www.w3.org/TR/hr-time-3/
[html]
HTML 표준. Anne van Kesteren; Domenic Denicola; Dominic Farolino; Ian Hickson; Philip Jägenstedt; Simon Pieters. WHATWG. Living Standard. URL: https://html.spec.whatwg.org/multipage/
[infra]
Infra 표준. Anne van Kesteren; Domenic Denicola. WHATWG. Living Standard. URL: https://infra.spec.whatwg.org/
[mediacapture-streams]
미디어 캡처 및 스트림. Cullen Jennings; Jan-Ivar Bruaroey; Henrik Boström; youenn fablet. W3C. 2025년 4월 24일. CRD. URL: https://www.w3.org/TR/mediacapture-streams/
[PERMISSIONS-POLICY]
권한 정책. Ian Clelland. W3C. 2025년 5월 6일. W3C 작업 초안. URL: https://www.w3.org/TR/permissions-policy-1/
[RFC2119]
요구 수준을 표시하기 위한 RFC에서의 핵심 단어. S. Bradner. IETF. 1997년 3월. Best Current Practice. URL: https://www.rfc-editor.org/rfc/rfc2119
[RFC8174]
RFC 2119 핵심 단어의 대소문자 모호성. B. Leiba. IETF. 2017년 5월. Best Current Practice. URL: https://www.rfc-editor.org/rfc/rfc8174
[WEBDRIVER2]
WebDriver. Simon Stewart; David Burns. W3C. 2025년 5월 12일. W3C 작업 초안. URL: https://www.w3.org/TR/webdriver2/
[WEBIDL]
Web IDL 표준. Edgar Chen; Timothy Gu. WHATWG. Living Standard. URL: https://webidl.spec.whatwg.org/

C.2 비규범적 참조

[ECMAScript]
ECMAScript 언어 명세. Ecma International. URL: https://tc39.es/ecma262/multipage/