Copyright © 2026 World Wide Web Consortium. W3C® liability, trademark and permissive document license rules apply.
컴퓨팅 압력 API는 웹사이트가 대상 기기의 CPU 압력 변화에 대응할 수 있는 방법을 제공하여, 웹사이트가 향상된 사용자 경험을 위해 리소스를 절충할 수 있도록 한다.
이 절에서는 이 문서가 발행된 시점의 상태를 설명한다. 현재 W3C 간행물 목록과 이 기술 보고서의 최신 개정판은 다음 W3C 표준 및 초안 색인에서 확인할 수 있다.
이 명세는 Chromium 기반 브라우저에 구현되어 있다. WebKit은 이 명세에 반대하는 입장을 공개했다. Mozilla의 입장은 보류 중이다.
이 명세가 CR 단계를 벗어나려면, 이 명세에 정의된 모든 기능에 대해 독립적인 구현이 최소 2개 이상 구현 보고서에 문서화되어야 한다.
이 문서는 기기 및 센서 워킹 그룹이 후보 권고안 초안으로 발행했으며, 권고안 트랙을 사용했다.
후보 권고안으로 발행되었다고 해서 W3C와 그 회원사가 이를 지지한다는 의미는 아니다. 후보 권고안 초안은 워킹 그룹이 후속 후보 권고안 스냅숏에 포함하려는 이전 후보 권고안 이후의 변경 사항을 통합한다.
이 문서는 초안이며 언제든지 다른 문서에 의해 업데이트되거나 대체되거나 폐기될 수 있다. 진행 중인 작업 이외의 것으로 이 문서를 인용하는 것은 적절하지 않다.
이 문서는 한 그룹이 작성했으며, 이 그룹은 다음 정책에 따라 운영된다: W3C 특허 정책. W3C는 모든 특허 공개의 공개 목록을 그룹의 결과물과 관련하여 관리하며, 해당 페이지에는 특허 공개 지침도 포함되어 있다. 특허에 대해 실제로 알고 있는 개인이 그 특허에 필수 청구항이 포함되어 있다고 판단한다면 다음에 따라 정보를 공개해야 한다. W3C 특허 정책 제6절.
이 문서에는 2025년 8월 18일 W3C 절차 문서가 적용된다.
이 절은 비규범적이다.
현대 애플리케이션은 현대적이고 만족스러운 사용자 경험을 제공하기 위해 시스템의 컴퓨팅 리소스를 완전히 활용할 때의 절충점과 이점 사이에서 균형을 유지해야 하는 경우가 많다.
예를 들어 많은 애플리케이션은 다양한 수준의 정교함으로 비디오 효과를 렌더링할 수 있다. 이러한 애플리케이션은 최상의 사용자 경험을 제공하는 동시에 사용자의 기기가 높은 압력 상태에 도달하지 않도록 하는 것을 목표로 한다.
처리 장치의 사용률이 100%에 근접하거나 자주 도달하면 서로 다른 태스크가 처리 시간을 확보하려고 경쟁하므로 좋지 않은 사용자 경험으로 이어질 수 있다. 이로 인해 속도가 느려질 수 있으며, 특히 입력 지연이 발생할 때 두드러진다. 또한 사용률이 장시간 100%에 근접하면 지속적인 부스트로 인해 처리 장치가 뜨거워질 수 있으며, 이는 스로틀링으로 이어져 사용자 경험을 더욱 악화할 수 있다.
열 제한으로 인해 많은 스마트폰, 태블릿 및 노트북은 만지기 불편할 정도로 뜨거워질 수 있다. 노트북과 데스크톱의 팬 소음은 대화를 방해하거나 사용자의 집중력을 저해할 정도로 커질 수 있다.
높은 압력 상태의 기기는 운영 체제가 사용자가 기다리는 태스크를 진행하는 스레드를 스케줄링하지 못할 수 있으므로 응답하지 않는 것처럼 보이는 경우가 많다. 다음도 참조한다. 사용 사례.
이 절은 비규범적이다.
기능 감지는 확립된 웹 개발 모범 사례이다. 이 주제에 관한 자료는 온라인과 오프라인 모두에 풍부하며, 이 절의 목적은 이를 더 논의하는 것이 아니라 하드웨어 종속 기능을 감지하는 맥락에서 살펴보는 것이다.
다음 기능 감지 예제를 살펴보자:
이 명세는 다음 개념을 정의한다:
컴퓨팅 기기는 중앙 처리 장치(CPU), 그래픽 처리 장치(GPU) 및 수많은 특수 처리 장치와 같은 매우 다양한 장치로 구성된다. 머신 러닝이나 컴퓨터 비전과 같은 특정 작업을 가속하도록 설계된 후자의 처리 장치는 점점 보편화되고 있다.
이 명세는 현재 유효한 소스 유형을 CPU라고도 하는 중앙 처리 장치로 정의한다. 이 명세의 향후 레벨에서는 선택적으로 추가 소스 유형을 도입할 수 있다.
PressureSource 열거형은 유효한 소스
유형을 나타낸다:
요청된 샘플링 간격은 하드웨어에서 얻을 샘플 사이의 원하는 간격을 나타내며, 밀리초 단위로 표현된다.
간격과 빈도는 서로 역수 관계이므로 요청된 샘플링 간격은 1000을 요청된 샘플링 간격 값으로 나누어 헤르츠(초당 주기 수) 단위의 요청된 샘플링 빈도로도 표현할 수 있다.
사용자 에이전트가 기반 플랫폼에서 텔레메트리 판독값을 얻는 빈도를 플랫폼 수집기의 샘플링 빈도로 정의하며, 이는 압력 관찰자의 요청된 샘플링 빈도와 다를 수 있다. 이 빈도는 헤르츠(초당 주기 수)로 측정된다.
압력 관찰자의 보고 빈도는 데이터 수집 단계를 실행하는 빈도이며, 샘플링 빈도를 절대 초과하지 않는다.
요청된 샘플링 빈도가 기반 플랫폼과 사용자 에이전트†가 지원하거나 허용하는 샘플링 빈도의 상한 또는 하한을 벗어나면 샘플링 빈도는 요청된 샘플링 빈도와 달라진다.
†이 명세는 다음에 설명된 대로 빈도를 추가로 난독화한다. 11.2.2 빈도 난독화.
사용자가 샘플링 빈도를 요청하지 않은 경우 샘플링 빈도는 구현 정의이다.
압력 소스는 하드웨어 카운터 또는 기반 프레임워크에 대한 추상적인
구현 정의
인터페이스로, PressureSource에서 정의한
소스 유형에 대한
텔레메트리 데이터를 제공한다. 압력 소스는
추가 소스의 데이터가 더 정확한 결과를 제공한다면
해당 데이터와 데이터 융합을 사용할 수 있다.
압력 소스에서 제공한 텔레메트리 데이터는 이 명세에서 다음 구조체로 표현되는 압력 소스 샘플이다. 이 구조체는 다음 항목으로 구성된다:
PressureState
.
압력 소스에는 연관된 최신 샘플이 있으며, 이는 압력 소스 샘플 또는 null이다. 초기값은 null이다.
플랫폼 수집기는 압력 소스에서 텔레메트리 샘플을 얻고, 이를 압력 상태로 변환하여 사용자 에이전트에 제공하는 추상 인터페이스이다.
플랫폼 수집기에는 다음과 같은 연관 데이터가 있다:
압력 소스에서 제공하고 최신 샘플의 데이터에 저장한 텔레메트리 데이터의 형식은 구현 정의이며, 플랫폼 수집기가 이를 압력 상태로 변환하는 과정도 구현 정의이다.
이 명세의 목적상 플랫폼 수집기의 범위는 플랫폼 수집기 매핑을 통해 전역 객체로 지정된다.
자동화를 위해 플랫폼 수집기에는 가상 압력 소스에 연결하여 시뮬레이션된 데이터를 조정된 압력 상태로 변환해야 하는 원시 플랫폼 데이터 대신 압력 상태로 사용하는 기능이 있어야 한다.
텔레메트리 데이터 수집에는 하드웨어 카운터 폴링이 수반되는 경우가 많으므로 비용이 들며, 데이터를 관찰하는 주체가 없다면 수행해서는 안 된다. 자세한 내용은 10.5 수명 주기 및 가비지 컬렉션을 참조한다.
플랫폼 수집기는 특정 빈도로 데이터를 샘플링한다. 사용자 에이전트는 개인정보 보호를 위해 가능한 경우 이 빈도를 수정하거나 특정 판독값을 무시하고 융합할 수 있다.
다음 사항을 권고한다: 사용자 에이전트는 압력 관찰자가 활성 상태일 때 이를 사용자에게 알리는 사용자 표시 알림을 제공하고, 진행 중인 작업을 차단하거나 알림을 간단히 닫을 수 있는 수단도 제공한다.
컴퓨팅 압력 API는 "compute-pressure" 토큰으로 식별되는
정책 제어 기능을 정의한다.
해당 기능의 기본 허용 목록은
'self'이다.
워커(전용 및 공유)는 자신을 소유한 문서에 설정된 권한 정책을 따른다.
공유 워커는 동일 출처의 다른 문서에서도 가져올 수 있으므로 여러 소유 문서를 갖는 경우가 많다. 이 경우 모든 소유 문서는 이 명세에서 정의한 정책 제어 기능을 사용하도록 허용되어야 한다.
전용 워커는 다른 워커에서 생성할 수 있으며, 이 경우 소유자 체인의 상위에 있는 첫 번째 소유 문서 또는 공유 워커의 경우 첫 번째 소유 문서들의 권한 정책을 사용한다.
각 전역 객체에는 다음이 있다:
PressureObserver 객체)로 구성된다.
사용자 에이전트에는 다음이 있다:
PressureSource 값의
지원되는 소스 유형 목록.
생성된 PressureObserver 객체에는
다음 내부 슬롯이 있다:
PressureUpdateCallback 유형의 [[Callback]].
PressureSource 문자열을 보유하고,
promise는 Promise 객체를 보유한다.
PressureRecord
객체로 구성된 대기열. 초기에는 비어 있다.
PressureSource를
최신 PressureRecord에 매핑하는
순서 있는 맵.
PressureSource를
양수에 매핑하는 순서 있는 맵. 주어진 소스 유형의 샘플링 간격을 나타낸다.
빈도 난독화 완화를 위해 생성된
PressureObserver 객체에는 다음 내부 슬롯이
추가로 있다:
PressureSource를 키로 사용하는
순서 있는 맵. 해당 키는 현재 압력 상태로의 전환을
유발한
소스 유형을 나타낸다.
순서 있는 맵의 값은
현재 관찰 창 시간 범위 내의 상태 변경 횟수를 나타내는
정수이다.
PressureSource를 키로 사용하는
순서 있는 맵. 해당 키는 마지막 PressureRecord의
소스 유형을 나타낸다.
순서 있는 맵의 값은
PressureRecord이다.
압력 상태는 웹사이트가 품질이나 서비스 또는 사용자 경험의 저하를 최소화하면서 컴퓨팅 및 시스템 압력의 변화에 대응할 수 있도록 하는 유용한 상태의 최소 집합을 나타낸다.
WebIDLenum PressureState { "nominal", "fair", "serious", "critical" };
PressureState 열거형은 다음 상태로 구성된 압력 상태를 나타낸다:
nominal": 대상 기기의 상태가 허용 가능한
수준이며 사용자에게 눈에 띄는
부정적인 영향이 없다.
fair": 대상 기기의 압력, 온도
및/또는 에너지 사용량이 약간 높아져
배터리 수명이 단축되거나 팬이 작동하여 소리가 들릴 수 있다.
그 외에는 대상 기기가 원활하게 실행되며 추가 작업을 처리할 수 있다.
serious": 대상 기기의 압력,
온도 및/또는 에너지 사용량이 지속적으로 매우 높다.
시스템은 열을 줄이기 위한 대응 조치로 스로틀링을 수행할 수 있다.
critical": 대상
기기 또는 시스템의 온도가 크게 상승했으며 잠재적인 문제를 방지하려면
냉각해야 한다.
기여 요인은 현재 압력 상태에 기여하는 기반 하드웨어 및 운영 체제 메트릭을 나타내며 구현 정의일 수 있다.
조정된 압력 상태는 압력 상태이며, 구현 정의 알고리즘이 소스 유형과 기타 구현 정의인 기여 요인 데이터를 입력으로 사용하여 결정한다. 이 알고리즘은 반드시 결정론적이지 않아야 하며 보정 방해 완화의 효과를 보장해야 한다.
기여 요인의 변화가 상당함 단계는 다음과 같다:
PressureUpdateCallback 콜백WebIDLcallback PressureUpdateCallback = undefined (
sequence<PressureRecord> changes,
PressureObserver observer
);
이 콜백은 압력 상태가 변경되면 호출된다.
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를 나타낸다.
new PressureObserver(callback)
생성자 단계는 다음과 같다:
[[Callback]]을 callback으로 설정한다.
observe(source, options)
메서드 단계는 다음과 같다:
NotAllowedError를
반환한다.
[[SampleIntervalMap]][source]를
options의 sampleInterval로
설정한다.
[[PendingObservePromises]]에
추가한다.
[[PendingObservePromises]]에서
tuple을 제거한다.
NotSupportedError로
거부하고
이 단계를 중단한다.
unobserve(source)
메서드 단계는 다음과 같다:
NotSupportedError"를
예외로 던진다.
[[QueuedRecords]]에서
source와 연결된 모든
records를 제거한다.
[[SampleIntervalMap]][source]를 제거한다.
[[LastRecordMap]][source]를 제거한다.
[[AfterPenaltyRecordMap]][source]를 제거한다.
[[PendingObservePromises]]의
각 (promiseSource, pendingPromise)에 대해 반복하여,
source가 promiseSource와 같다면
pendingPromise를 AbortError로 거부한다.
disconnect() 메서드
단계는 다음과 같다:
[[QueuedRecords]]를
비운다.
[[SampleIntervalMap]]을 지운다.
[[LastRecordMap]]을 지운다.
[[AfterPenaltyRecordMap]]을 지운다.
[[PendingObservePromises]]의
각 (promiseSource, pendingPromise)에 대해 반복하여
pendingPromise를 AbortError로 거부한다.
takeRecords()
메서드 단계는 다음과 같다:
[[QueuedRecords]]의
복제본으로 둔다.
[[QueuedRecords]]를
비운다.
knownSources getter 단계는 다음과
같다:
WebIDL[Exposed=(DedicatedWorker,SharedWorker,Window), SecureContext]
interface PressureRecord {
readonly attribute PressureSource source;
readonly attribute PressureState state;
readonly attribute DOMHighResTimeStamp time;
[Default] object toJSON();
};
생성된 PressureRecord 객체에는
다음 내부 슬롯이 있다:
PressureSource 유형의
[[Source]] 값.
PressureState 유형의
[[State]] 값.
DOMHighResTimeStamp 유형의
[[Time]] 값으로,
해당 값은
알림을 생성한 PressureObserver
인스턴스와 연결된 전역 객체의
시간 원점을 기준으로
시스템에서 데이터를 얻은
시각에 해당한다.
source getter 단계는 해당 객체의 [[Source]] 내부 슬롯을 반환한다.
PressureRecord.toJSON이 호출되면 Web IDL
표준의 기본 toJSON 단계를 실행한다.
WebIDLdictionary PressureObserverOptions {
[EnforceRange] unsigned long sampleInterval = 0;
};
sampleInterval 멤버는
밀리초 단위로 표현된 요청된 샘플링
간격을 나타낸다. 값이 0으로 설정된 경우 시스템은
PressureUpdateCallback을
PressureState가 변경된 경우에만 호출한다.
각 전역 객체는 해당 등록된 관찰자 목록의 등록된 관찰자에 대한 강한 참조를 갖는다(소스마다 하나씩).
이 절에서는 사용자 에이전트가 이 명세를 구현할 때 수행해야 하는 단계를 설명한다.
인수 observer가 주어졌을 때 관찰 창 재설정 단계는 다음과 같다:
[[ObservationWindow]]을
구현 정의 무작위
정숫값으로 설정한다. 이 값은
구현 정의 범위 내의 밀리초 단위 값이다.
[[MaxChangesThreshold]]을
구현 정의 무작위
정숫값으로 설정한다.
이 값은 observationWindow 동안 허용되는 최대 변경 횟수이며 구현 정의 범위 내에 있다.
[[PenaltyDuration]]을
구현 정의 무작위
정숫값으로 설정한다.
이 값은 구현 정의 범위 내의 밀리초 단위 값이다.
[[ChangesCountMap]]
맵을 비운다.
[[ObservationWindow]]
시간이 지나면 다른 무작위 값을 사용하여 이 단계를 다시 실행하는 타이머를 시작한다.
관련 전역 객체 relevantGlobal의 소유 문서 집합을 결정하려면:
Window라면
relevantGlobal의 연결된 문서를
owningDocumentSet에 추가한다.
WorkerGlobalScope
relevantGlobal의 소유자 집합에 있는 각
owner에 대해:
Document라면
owner를 owningDocumentSet에 추가한다.
WorkerGlobalScope라면,
owningDocumentSet을 owningDocumentSet과
owner의 소유 문서 집합의 합집합으로 설정한다.
인수 document가 주어졌을 때 문서에 암시적 포커스가 있음 단계는 다음과 같다:
인수 observer가 주어졌을 때 데이터를 수신할 수 있음 단계는 다음과 같다:
Window 객체라면:
WorkerGlobalScope
객체라면:
[[LastRecordMap]][source]가 존재하지 않으면 true를 반환한다.
[[LastRecordMap]][source]로 둔다.
[[SampleIntervalMap]][source]로 둔다.
[[Time]]으로 둔다.
[[SampleIntervalMap]][source] > 0이면 true를 반환한다.
[[LastRecordMap]][source]가 존재하지 않으면 true를 반환한다.
[[LastRecordMap]][source]로 둔다.
[[State]]가
state와 같지 않으면 true를 반환한다.
[[ChangesCountMap]][source]를 1 증가시킨다.
[[ChangesCountMap]][source]
≤ observer.[[MaxChangesThreshold]]인지 반환한다.
소스 유형 source와 relevantGlobal이 주어졌을 때 가상 압력 소스 가져오기를 수행하려면 다음 단계를 수행한다. 이 단계는 가상 압력 소스 또는 null을 반환한다.
Window 객체라면:
DedicatedWorkerGlobalScope
객체라면:
소스 유형 source 및 relevantGlobal이 주어졌을 때 데이터 수집 활성화를 수행하려면 다음 단계를 수행한다:
소스 유형 source 및 relevantGlobal이 주어졌을 때 데이터 수집 비활성화를 수행하려면 다음 단계를 수행한다:
relevantGlobal, source 및 platformCollector이 주어졌을 때 데이터 수집 단계는 다음과 같다:
PressureState로 설정한다.
PressureRecord 객체로 둔다. 객체의
[[Source]]는
source로,
[[State]]는 state로,
[[Time]]은
timeValue로 설정한다.
[[AfterPenaltyRecordMap]][source]가
존재한다면:
[[AfterPenaltyRecordMap]][source]를
record로 설정한다.
[[AfterPenaltyRecordMap]][source]를
record로 설정한다.
[[ChangesCountMap]][source]를
0으로 설정한다.
[[PenaltyDuration]]
지속 시간의 타이머를 생성한다:
[[AfterPenaltyRecordMap]][source]가
존재한다면:
[[AfterPenaltyRecordMap]][source]로
둔다.
[[AfterPenaltyRecordMap]][source]를
제거한다.
인수 observer, source, record가 주어졌을 때 레코드를 대기열에 추가하려면 다음 단계를 실행한다:
[[QueuedRecords]]의 크기가
최대 대기 레코드 수보다 크면 첫 번째 항목을 제거한다.
[[QueuedRecords]]에 추가한다.
[[LastRecordMap]][source]를 record로
설정한다.
PressureObserver 태스크 소스는 태스크 소스이며, 10.6.5 압력 관찰자에게 알림을 위한 태스크를 스케줄링하는 데 사용된다.
relevantGlobal이 입력으로 주어졌을 때 압력 관찰자 태스크를 대기열에 추가하려면 다음 단계를 실행한다:
relevantGlobal이 입력으로 주어졌을 때 압력 관찰자에게 알림을 수행하려면 다음 단계를 실행한다:
[[QueuedRecords]]의 복제본으로 둔다.
[[QueuedRecords]]를 비운다.
[[Callback]]을 호출한다.
이때 « records, observer » 및
"report"를 사용한다.
이 명세는 Document document가 주어졌을
때
다음 문서 언로드 정리 단계를 정의한다:
WorkerGlobalScope
relevantGlobal의
종료 중 플래그가 true로 설정될 때마다
다음
단계를 수행한다:
출처를 공유하지 않는 사이트가 고유하거나 매우 정밀한 값에 동시에 접근할 수 있다면, 동일 출처가 아닌 사이트 전반에서 사용자를 식별할 수 있다. 이 공격은 11.2.1 데이터 최소화, 11.2.2 빈도 난독화, 그리고 11.2.7 동일 출처 제한으로 완화된다.
컴퓨터 보안에서 은닉 채널은 통신이 허용되어서는 안 되는 프로세스 사이에서 정보를 전송할 수 있는 기능을 만든다. 현대적인 다중 프로세스 웹 엔진에서는 일반적으로 각 창이나 탭이 자체 프로세스에 존재한다(동일 출처인 문서나 동일 사이트인 사이트는 일반적으로 같은 프로세스를 공유한다). 이 API를 사용하면 교차 사이트 은닉 채널 C를 만들 수 있다. 한 탭의 사이트 A가 CPU 상태를 조작한 후 먼저 채널 C로 브로드캐스트한다. 그런 다음 다른 탭의 사이트 B(사이트 A와 동일 사이트가 아님)가 이 API를 사용하여 CPU 상태가 변경된 시점을 파악함으로써 채널 C에서 브로드캐스트된 데이터를 읽는다. 이 프로세스는 사이트 A와 B 모두에서 스크립트가 실행되는 동안 반복된다.
이 공격은 11.2.2 빈도 난독화 및 11.2.5 보정 방해로 완화된다. 구현자는 장시간 실행되는 스크립트에 이러한 완화책을 모두 고려하는 것이 좋다.
표적 비익명화 공격은 사용자의 익명성을 위협하는 중대한 위협 유형이다. 이러한 공격을 사용하면 악의적이거나 부분적으로 침해된 웹사이트(“악성 사이트”라고 함)가 웹사이트 방문자에게 이메일 주소나 소셜 미디어 계정명과 같은 특정 공개 식별자가 있는지를 확인할 수 있다.
일부에게 익명성은 사치일 수 있지만, 어떤 사람들에게는 그보다 훨씬 중요하며 생존의 문제이기도 하다. 예를 들어 정치 시위에 참여하거나 민감한 주제를 취재하는 언론인으로 일하는 사람 등을 생각해 보라.
공격자는 예를 들어 공개 리소스 공유 서비스(“피해자 사이트”)를 사용하여 표적과 리소스를 비공개로 공유한 다음, 부채널을 통해 리소스를 로드할 때 발생하는 부수 효과(성공적인 접근을 나타냄)를 측정할 수 있다. 로그인한 방문자가 삽입된 리소스에 성공적으로 접근할 수 있다면, 현재 방문자가 실제로 의도한 표적임을 나타낸다.
구체적으로, 전체 CPU 압력에 관한 신뢰할 수 있는 정보를 노출하면 공격 사이트가 교차 출처 탐색 대상(예: 다른 사이트의 iframe 또는 팝업 창)이 CPU 집약적인 작업을 수행했는지 파악할 수 있다.
팝언더 및 탭언더와 같은 기법을 사용하여 로딩을 사용자에게 숨길 수 있다.
가능한 공격 중 하나는 악성 웹사이트가 사용자가 로그인한 피해자 사이트의 리소스 (예: 동영상 스트리밍 사이트 또는 온라인 문서 편집기)에 대해 팝업 등을 열고, 특정 사용자와 공유된 리소스를 가리키게 하는 것이다.
리소스를 로드할 때 CPU 압력이 증가한다고 가정하면, 이는 공격 사이트에 사용자가 해당 리소스에 접근할 수 있는 계정으로 로그인했는지를 알려주는 부채널을 형성하여 사용자의 익명성을 해제한다.
현대 CPU는 높은 압력에서 빠르게 회복하므로, 가능한 완화 전략 중 하나는 팝업 및 iframe 콘텐츠를 로드한 후 몇 초 동안 판독을 일시적으로 비활성화하는 것이다.
이 명세는 기반 플랫폼의 저수준 세부 정보와 관련된 데이터의 노출을 가치가 높은 사용 사례를 처리하는 데 필요한 최소한으로 제한하기 위해 일반적인 데이터 최소화 원칙을 준수한다. 여기에는 기기에 관한 식별 정보의 노출 제한을 고려하는 것도 포함된다.
이 명세의 맥락에서 데이터 최소화 원칙을 구체적으로 적용하는 방법은 11.2.2 빈도 난독화 및 11.2.7 동일 출처 제한에서 설명한다.
이 명세에서는 구현 정의 슬라이딩 관찰 창에서 압력 변경 횟수를 추적하고, 압력 변경 횟수가 구현 정의 임계값을 초과하면 플래그를 설정하는 빈도 난독화 완화책을 구현하도록 요구한다. 마찬가지로 여러 상태에 걸쳐 압력 상태 변경 횟수가 많은 것과 같은 비정상 활동을 구현이 관찰하고, 동일한 방식으로 이 플래그를 설정하는 것도 권장한다.
이 플래그가 설정되면 구현은 압력 관찰자에게 페널티를 부여하는 것이 좋다. 이 페널티가 지속되는 동안에는 평소처럼 압력 상태 변경을 스크립트에 알릴 수 없다. 이 페널티의 지속 시간은 구현 정의이며 무작위화하는 것이 권장된다. 페널티 이후 압력 관찰자에게 알림이 작업을 재개하면 최신 압력 상태만 보고하고, 이 페널티 동안 플랫폼 수집기에서 받은 모든 중간 상태 정보는 무시한다.
구현 경험에 기반하여 구현자는 다음을 사용해야 한다:
[[MaxChangesThreshold]] 내부
슬롯에는 50회에서 100회 사이의 변경 범위.
[[PenaltyDuration]]
내부 슬롯에는 5000밀리초에서 10000밀리초 사이의 범위.
이 절은 비규범적이다.
구현 경험에 기반하여 구현자는 다음을 사용하는 것이 좋다:
[[ObservationWindow]] 내부 슬롯에는
300000밀리초(5분)에서 600000밀리초(10분) 사이의 범위.
보정 과정에서 공격자는 조작된 워크로드가 가하는 압력에 대한 응답으로 이 API가 특정 압력 상태로의 전환을 가장 높은 확률로 보고하도록 CPU를 조작하려 한다. 이 보정 방해 완화책은 이러한 압력 상태 전환에 기여하는 구현 정의 저수준 하드웨어 측정치를 런타임에 조금씩 변경하여, 이 보정 과정이 성공하지 못하게 하거나 속도를 늦출 수 있다. 초기 보정이 성공하더라도 이 완화책이 계속 실행되면서 런타임에 그 결과가 무효화된다. 다시 보정하려는 모든 시도도 마찬가지로 완화된다.
이 절은 비규범적이다.
구현 경험에 기반하여 구현자는 120000밀리초(2분)에서 240000밀리초(4분) 사이 범위의 무작위 시간 값에 완화책을 적용하는 것이 좋다.
기본적으로 데이터 전달은 활성 PIP 세션의 개시자와 동일한 출처에서 제공된 문서, 캡처 중인 문서, 또는 존재하는 경우 시스템 포커스가 있는 문서로 제한된다.
위 규칙에 따라 데이터 전달 요건을 충족하는 문서는 자식 탐색 가능 객체의 문서에 이를 위임할 수 있다.
이 기능은 선언된 정책을 통해서만 iframe과 같은 서드 파티 컨텍스트로 확장할 수 있다.
공유 작업자는 최상위 문서와 연결된 iframe 등 여러 문서에서 공유될 수 있다. 소유자 집합의 문서 중 하나가 위의 데이터 전달 요건을 충족하면 공유 작업자도 데이터 전달 요건을 충족한다. 즉, 삽입된 iframe이 데이터를 삽입 문서에 전달할 수 있다.
컴퓨팅 압력 API는 사용자 경험을 개선하는 데 중점을 둔다. 이 API를 기반으로 구축된 애플리케이션이 접근성에 긍정적인 영향을 줄 수 있는 방법은 두 가지이다.
API 사용자는 이 두 가지 기회를 모두 고려하는 것이 중요하다. 다음은 몇 가지 예이다:
컴퓨팅 압력 API는 인터페이스를 완전히 시험하려면 예측 가능한 방식으로 응답하는 물리적 하드웨어 기기가 필요하므로 테스트 작성자에게 어려움을 준다.
이 문제를 해결하기 위해 이 문서는 실제 압력 소스처럼 동작하면서 특정 속성을 가질 수 있고 판독값을 사용자가 전적으로 정의할 수 있는 가상 압력 소스를 정의하고 제어할 수 있도록 하는 [WEBDRIVER2] 확장 명령을 정의한다.
가상 압력 소스는 실제 압력 소스의 동작을 제어된 방식으로 모의하는 압력 소스이다. 가상 압력 소스는 연결된 0개 이상의 플랫폼 수집기에 압력 변경을 보고한다.
그러나 실제 압력 소스와 달리, 플랫폼
수집기가 압력 상태로 처리해야 하는
구현 정의 값을 보고하는 대신,
압력 상태 값을 직접 보고한다. 다시 말해,
가상 압력 소스의 압력
소스 샘플의
데이터는 PressureState이다.
모든 압력 소스와 관련된 데이터(예: 압력 소스 샘플) 외에도, 각 가상 압력 소스에는 다음 항목이 있다:
각 최상위 탐색 가능 객체에는 가상 압력 소스 매핑이 있다. 이는 소스 유형을 가상 압력 소스에 대응시키는 순서 있는 맵이다.
| HTTP 메서드 | URI 템플릿 |
|---|---|
| POST | /session/{session id}/pressuresource |
이 확장 명령은 지정된
소스 유형의 새 가상 압력 소스를 생성한다.
같은 소스 유형의
PressureObserver
인스턴스에서 observe()를 호출하면,
가상 압력 소스가
13.1.1.2
가상 압력 소스 삭제가 실행될 때까지 해당 인스턴스의
기반 압력 소스로 사용된다.
| 매개변수 이름 | 값 유형 | 필수 |
|---|---|---|
| type | String | 예 |
| supported | Boolean | 아니요 |
session, URL variables 및 parameters가 주어졌을 때 원격 단 단계는 다음과 같다:
| HTTP 메서드 | URI 템플릿 |
|---|---|
| DELETE | /session/{session id}/pressuresource/{type} |
이 확장 명령은 지정된 가상 압력 소스를 삭제한다. 즉, 주어진 소스 유형의 데이터를 사용할 수 있다면 가상 방식이 아닌 일반적인 방식으로 전달한다.
session, URL variables 및 parameters가 주어졌을 때 원격 단 단계는 다음과 같다:
| HTTP 메서드 | URI 템플릿 |
|---|---|
| POST | /session/{session id}/pressuresource/{type} |
이 확장 명령을 사용하면 새 압력 소스 샘플을 푸시하여 가상 압력 소스의 상태를 업데이트할 수 있다.
| 매개변수 이름 | 값 유형 | 필수 |
|---|---|---|
| sample |
PressureState
|
예 |
session, URL variables 및 parameters가 주어졌을 때 원격 종단 단계는 다음과 같다:
PressureState가 아니면,
WebDriver 오류 코드가
잘못된 인수인
오류를 반환한다.
이 절은 비규범적이다.
const samples = [];
function pressureChange(records, observer) {
for (const record of records) {
samples.push(record.state);
// 20개의 샘플만 필요하다.
if (samples.length == 20) {
observer.disconnect();
return;
}
}
}
const observer = new PressureObserver(pressureChange);
observer.observe("cpu");
다음 예시에서는 압력이 critical 상태가 될 때 동시 동영상 스트림 수를 줄이려고 한다. 단순화를 위해 이 상태만 고려한다.
스트림 수를 줄이더라도 critical 상태에서 벗어나지 못하거나 적어도 즉시 벗어나지는 못할 수 있으므로, 여전히 critical 상태에 있는 동안 30초마다 한 번에 스트림 하나씩 줄이는 전략을 사용한다.
이를 위해 콜백이 최소한 30초마다 한 번 또는 상태가 실제로 변경될 때 호출되도록 한다. 상태가 변경되면 간격 타이머를 재설정한다.
let timerId = -1;
function pressureChange(records) {
// 실제 상태 변경 또는 setTimeout 호출(아래 참조)로 이 함수가 호출될 때마다
// 타이머를 지운다.
if (timerId > 0) {
clearTimeout(timerId);
}
// critical 상태가 되면 30초마다 여전히 critical 상태인지 다시 확인하고,
// 그렇다면 동시 스트림 수를 더 줄이려고 한다.
// 이를 위해 변경 사항이 없을 때 마지막 결과와 함께 이 함수를 다시 호출하는
// 30초 타이머를 생성한다.
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");
다음 예시에서는 콜백이 마지막으로 호출된 이후 누적된 나머지
records를 가져와 takeRecords()를
사용하는 방법을 보여준다.
disconnect() 전에
이 작업을 수행하는 것이 좋다. 그렇지 않으면
disconnect()가
레코드를 지우며 레코드는 영원히 손실된다.
예를 들어 벤치마킹 워크로드 중의 압력을 측정하여 워크로드가 지속되는 정확한 시간 동안의 압력 원격 측정값을 얻고자 할 수 있다. 이는 작업이 완료되면 모든 관찰자의 연결을 즉시 해제하고, 이벤트 루프 주기의 일부로 아직 전달되지 않았을 수 있는 현재 시점까지의 보류 중인 압력 원격 측정값을 수동으로 요청하는 것을 의미한다.
function logWorkloadStatistics(records) {
// records로 무언가를 수행한다.
}
const observer = new PressureObserver(logWorkloadStatistics);
observer.observe("cpu");
// 보류 중인 상태 변경 레코드를 읽는다. 그렇지 않으면 연결을 해제할 때
// 레코드가 지워진다.
const records = observer.takeRecords();
logWorkloadStatistics(records);
observer.disconnect();
다음 예시에서는 source를 사용해
unobserve()를 호출하여
관찰자가 특정 source의 감시를 중지하도록 하는 방법을 보여준다.
const observer = new PressureObserver(records => { /* records로 무언가를 수행한다. */ });
observer.observe("cpu");
observer.observe("gpu");
// 이제 'cpu' 또는 'gpu'의 압력 상태가 변경될 때마다 콜백이 호출된다.
observer.unobserve("gpu");
// 이제 'cpu'의 압력 상태가 변경될 때만 콜백이 호출된다.
다음 예시에서는 disconnect()를 호출하여
관찰자가 모든 상태 변경 감시를 중지하도록 하는 방법을 보여준다.
disconnect()를 호출하면
이전 observe()
호출에서 관찰한 모든 소스의 관찰을
중지한다.
또한 마지막으로 콜백이 호출된 이후 수집된 보류 중인 모든 레코드를 지운다.
const observer = new PressureObserver(records => { // records로 무언가를 수행한다. });
observer.observe("cpu");
observer.observe("gpu");
// 어느 정도 시간이 지난 후...
observer.disconnect();
// 앞서 disconnect()를 호출했으므로 records는 빈 배열이다.
const records = observer.takeRecords();
비규범적으로 표시된 절뿐 아니라 이 명세의 모든 작성 지침, 다이어그램, 예시 및 참고는 비규범적이다. 이 명세의 그 밖의 모든 내용은 규범적이다.
이 문서에서 핵심 단어 MAY, MUST 및 RECOMMENDED는 여기에 표시된 것처럼 모두 대문자로 나타나는 경우에만 BCP 14 [RFC2119] [RFC8174]에 설명된 대로 해석해야 한다.
이 명세는 하나의 제품, 즉 명세에 포함된 인터페이스를 구현하는 사용자 에이전트의 적합성 기준을 정의한다.
이 절은 비규범적이다.
다음 분들이 보내 주신 귀중한 피드백과 조언에 깊이 감사드린다. 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에게 감사드린다.
실제 시나리오에서 이 API를 개선하는 데 도움이 된 피드백과 실무 실험을 제공한 Zoom 엔지니어링 팀의 Amanda Zhao, Fidel Tian, Zhiliang Wang 및 그 밖의 분들께 특별히 감사드린다.
이 절은 비규범적이다.
[[AfterPenaltyRecordMap]]:
PressureObserver의 내부 슬롯
§7.
[[Callback]]:
PressureObserver의 내부 슬롯
§7.
[[ChangesCountMap]]:
PressureObserver의 내부 슬롯
§7.
constructor():
PressureObserver의 생성자
§10.2.1
"cpu":
PressureSource의 열거형 값
§3.2
"critical":
PressureState의 열거형 값
§8.
disconnect():
PressureObserver의 메서드
§10.2.4
"fair":
PressureState의 열거형 값
§8.
knownSources:
PressureObserver의 속성
§10.2.6
[[LastRecordMap]]:
PressureObserver의 내부 슬롯
§7.
[[MaxChangesThreshold]]:
PressureObserver의 내부 슬롯
§7.
"nominal":
PressureState의 열거형 값
§8.
[[ObservationWindow]]:
PressureObserver의 내부 슬롯
§7.
observe():
PressureObserver의 메서드
§10.2.2
[[PenaltyDuration]]:
PressureObserver의 내부 슬롯
§7.
[[PendingObservePromises]]:
PressureObserver의 내부 슬롯
§7.
PressureObserver 인터페이스
§10.2
PressureObserverOptions 사전
§10.4
PressureRecord 인터페이스
§10.3
PressureSource 열거형
§3.2
PressureState 열거형
§8.
PressureUpdateCallback
§10.1
[[QueuedRecords]]:
PressureObserver의 내부 슬롯
§7.
sampleInterval:
PressureObserverOptions의 멤버
§10.4.1
[[SampleIntervalMap]]:
PressureObserver의 내부 슬롯
§7.
"serious":
PressureState의 열거형 값
§8.
source:
PressureRecord의 속성
§10.3.1
[[Source]]:
PressureRecord의 내부 슬롯
§10.3
state:
PressureRecord의 속성
§10.3.2
[[State]]:
PressureRecord의 내부 슬롯
§10.3
takeRecords():
PressureObserver의 메서드
§10.2.5
time:
PressureRecord의 속성
§10.3.3
[[Time]]:
PressureRecord의 내부 슬롯
§10.3
toJSON:
PressureRecord의 메서드
§10.3.4
unobserve():
PressureObserver의 메서드
§10.2.3
Document 인터페이스
Node의 경우)
ECMAScript의 경우)
globalThis 속성
(globalThis의 경우)
DOMHighResTimeStamp
WorkerGlobalScope의 경우)
DedicatedWorkerGlobalScope 인터페이스
Document의 경우)
iframes 요소
WorkerGlobalScope의 경우)
WorkerGlobalScope의 경우)
Document의 경우)
Window 인터페이스
WorkerGlobalScope 인터페이스
list의 경우)
set의 경우)
map의 경우)
list의 경우)
list의 경우)
map의 경우)
iteration의 경우)
list의 경우)
list의 경우)
map의 경우)
list의 경우)
struct의 경우)
map의 경우)
list의 경우)
map의 경우)
list의 경우)
set의 경우)
map의 경우)
AbortError 예외
[Default] 확장 속성
[EnforceRange] 확장 속성
[Exposed] 확장 속성
FrozenArray 인터페이스
NotAllowedError 예외
NotSupportedError 예외
object
유형
Promise 인터페이스
promise의 경우)
[SameObject] 확장 속성
[SecureContext] 확장 속성
TypeError 예외
undefined 유형
unsigned long 유형
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;
};
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in: