1. 소개
사용자 지연(latency)은 웹 애플리케이션의 중요한 품질 벤치마크입니다.
자바스크립트 기반 메커니즘은 애플리케이션 내에서 사용자 지연 측정을 위한 포괄적인 계측을 제공할 수 있지만,
많은 경우에 전체 엔드투엔드 지연 상황을 완전히 제공하지 못합니다. 이 문서는 문서에 있는 리소스와 관련된
완전한 타이밍 정보를 자바스크립트 메커니즘이 수집할 수 있도록 허용하는 PerformanceResourceTiming
인터페이스를 소개합니다. Navigation Timing 2
[NAVIGATION-TIMING-2]는 내비게이션과 연관된 추가적인 타이밍 정보를 제공하기 위해 이 명세를
확장합니다.
예를 들어, 다음 자바스크립트는 리소스를 가져오는 데 걸리는 시간을 간단히 측정하려는 시도를 보여줍니다:
<!doctype html> < html > < head > </ head > < body onload = "loadResources()" > < script > function loadResources() { var start= new Date(). getTime(); var image1= new Image(); var resourceTiming= function () { var now= new Date(). getTime(); var latency= now- start; alert( "End to end resource fetch: " + latency); }; image1. onload= resourceTiming; image1. src= 'https://www.w3.org/Icons/w3c_main.png' ; } </ script > < img src = "https://www.w3.org/Icons/w3c_home.png" > </ body > </ html >
이 스크립트는 리소스를 가져오는 데 걸리는 시간을 측정할 수는 있지만, 다양한 단계에서 소비된 시간을 세분화할 수는 없습니다. 또한, 마크업에 기술된 리소스를 가져오는 데 걸리는 시간을 쉽게 측정할 수 없습니다.
사용자 경험에 대한 완전한 정보를 제공할 필요를 해결하기 위해, 이 문서는 PerformanceResourceTiming
인터페이스를 소개합니다.
이 인터페이스는 자바스크립트 메커니즘이 애플리케이션 내에서 클라이언트 측 완전한 지연 측정을 제공할 수 있게 합니다. 이
인터페이스를 사용하면 이전 예제를 수정하여 사용자가 인지하는 리소스 로드 시간을 측정할 수 있습니다.
다음 스크립트는 페이지 내의 모든 리소스를 가져오는 데 걸리는 시간을 계산합니다. 마크업에 정의된 리소스도 포함됩니다.
이 예제는 이 페이지가 https://www.w3.org에 호스팅된다고 가정합니다. 또한 PerformanceResourceTiming
인터페이스를 사용하여 리소스 가져오기 각 단계에 소요된 시간을 더 세부적으로 측정할 수도 있습니다.
<!doctype html> < html > < head > </ head > < body onload = "loadResources()" > < script > function loadResources() { var image1= new Image(); image1. onload= resourceTiming; image1. src= 'https://www.w3.org/Icons/w3c_main.png' ; } function resourceTiming() { var resourceList= window. performance. getEntriesByType( "resource" ); for ( i= 0 ; i< resourceList. length; i++ ) { if ( resourceList[ i]. initiatorType== "img" ) { alert( "End to end resource fetch: " + ( resourceList[ i]. responseEnd- resourceList[ i]. startTime)); } } } </ script > < img id = "image0" src = "https://www.w3.org/Icons/w3c_home.png" > </ body > </ html >
2. 용어
"a Foo object"라는 표현은 실제로 인터페이스인 Foo 대신에
때때로 더 정확한 표현인 "인터페이스 Foo를 구현하는 객체" 대신 사용됩니다.
이 문서 전반에서 모든 시간 값은 문서의 내비게이션 시작 시점 이후의 밀리초로 측정됩니다 [HR-TIME]. 예를 들어, 문서의 내비게이션 시작은 시간 0에서 발생합니다.
이 시간의 정의는 High Resolution Time 명세서 [HR-TIME]를 기반으로 하며, Navigation Timing 명세서에서 사용되는 시간 정의와 다릅니다. Navigation Timing에서는 시간이 1970년 1월 1일 자정(UTC) 이후의 밀리초로 측정됩니다.
3. 리소스 타이밍
3.1. 소개
PerformanceResourceTiming
인터페이스는 가져온(fetched) http(s) 리소스의
타이밍 측정을 용이하게 합니다. 예를 들어, 이 인터페이스는
XMLHttpRequest
객체 [XHR],
HTML 요소 [HTML]의
iframe,
img,
script,
object,
embed
및
link
(link type이 stylesheet인
경우),
SVG 요소 [SVG11]의 svg 등과
EventSource에
대해 사용 가능합니다.
3.2.
PerformanceResourceTiming
인터페이스에 포함된 리소스
이 절은 비규범적입니다.
비-널 클라이언트에 의해 요청(Request)된 리소스는 해당 클라이언트의
Performance Timeline에 PerformanceResourceTiming
객체로 포함됩니다. 다만 fetching 과정의 일부로 타임라인에서 제외된 경우는 예외입니다. HTTP 캐시에서 검색된 리소스도
PerformanceResourceTiming
객체로 Performance Timeline에 포함됩니다. 가져오기가 시작되었지만 이후 중단된 리소스(예: 네트워크 오류로 인한)는
시작 및 종료 타이밍과 함께 Performance Timeline에 PerformanceResourceTiming
객체로 포함됩니다.
예시:
- 같은 정규화된(canonical) URL이 두 개의 HTML
IMG요소의src로 사용되는 경우, 첫 번째 HTMLIMG요소가 시작한 해당 리소스의 가져오기(fetch)는PerformanceResourceTiming객체로 Performance Timeline에 포함됩니다. 사용자 에이전트는 두 번째 IMG 요소에 대해 URL을 재요청하지 않고 첫 번째 IMG 요소를 위해 시작된 기존 다운로드를 대신 사용할 수 있습니다. 이 경우 첫 번째IMG요소에 의한 리소스의 가져오기만이 Performance Timeline에 기록될 수 있습니다. - HTML
IMG요소의src속성이 스크립트로 변경되는 경우, 원래 리소스의 가져오기와 새 URL의 가져오기가 모두PerformanceResourceTiming객체로 Performance Timeline에 포함됩니다. - 만약 HTML
IFRAME요소가 마크업으로 추가되었으나src속성이 지정되지 않았다면, 사용자 에이전트는 해당IFRAME에 대해about:blank문서를 로드할 수 있습니다. 이후 스크립트로 동적으로src속성이 변경되면 사용자 에이전트는IFRAME의 새 URL 리소스를 가져오기할 수 있습니다. 이 경우 새 URL에 대한 가져오기만이PerformanceResourceTiming객체로 Performance Timeline에 포함됩니다. - 동일한 정규화된 URL에 대해 XMLHTTPRequest가 두 번 생성된 경우, 해당 리소스에 대한 두 번의
가져오기가 모두
PerformanceResourceTiming객체로 Performance Timeline에 포함됩니다. 이는 두 번째 XMLHttpRequest에 대한 리소스의 가져오기가 첫 번째 XMLHttpRequest에 대해 발행된 다운로드를 재사용할 수 없기 때문입니다. - 페이지에 HTML
IFRAME요소가 포함된 경우, 부모 문서의 Performance Timeline에는 오직IFRAME의src속성으로 요청된 리소스만 포함됩니다.IFRAME문서가 요청하는 서브리소스는 해당IFRAME문서의 Performance Timeline에 포함되며 부모 문서의 Performance Timeline에는 포함되지 않습니다. - HTML
IMG요소가 소스로data: URI를 사용할 경우, 이 리소스는PerformanceResourceTiming객체로 Performance Timeline에 포함되지 않습니다.PerformanceResourceTiming항목은 오직 http(s) 리소스에 대해서만 보고됩니다. - 리소스 가져오기가 네트워크 오류(예: DNS, TCP 또는 TLS 오류)로 중단된 경우, 해당 가져오기는
PerformanceResourceTiming객체로 Performance Timeline에 포함되며startTime,fetchStart,duration,responseEnd만 설정됩니다. - 가져오기가 가져오기 전제 조건(fetch precondition)을 실패(예: 혼합 콘텐츠, CORS 제한, CSP 정책 등)하여 중단된 경우,
해당 리소스는 Performance Timeline에
PerformanceResourceTiming객체로 포함되지 않습니다.
3.3. PerformanceResourceTiming 인터페이스
[Exposed =(Window ,Worker )]interface :PerformanceResourceTiming PerformanceEntry {readonly attribute DOMString ;initiatorType readonly attribute DOMString ;deliveryType readonly attribute ByteString ;nextHopProtocol readonly attribute DOMHighResTimeStamp ;workerStart readonly attribute DOMHighResTimeStamp ;redirectStart readonly attribute DOMHighResTimeStamp ;redirectEnd readonly attribute DOMHighResTimeStamp ;fetchStart readonly attribute DOMHighResTimeStamp ;domainLookupStart readonly attribute DOMHighResTimeStamp ;domainLookupEnd readonly attribute DOMHighResTimeStamp ;connectStart readonly attribute DOMHighResTimeStamp ;connectEnd readonly attribute DOMHighResTimeStamp ;secureConnectionStart readonly attribute DOMHighResTimeStamp ;requestStart readonly attribute DOMHighResTimeStamp ;finalResponseHeadersStart readonly attribute DOMHighResTimeStamp ;firstInterimResponseStart readonly attribute DOMHighResTimeStamp ;responseStart readonly attribute DOMHighResTimeStamp ;responseEnd readonly attribute DOMHighResTimeStamp ;workerRouterEvaluationStart readonly attribute DOMHighResTimeStamp ;workerCacheLookupStart readonly attribute DOMString ;workerMatchedRouterSource readonly attribute DOMString ;workerFinalRouterSource readonly attribute unsigned long long ;transferSize readonly attribute unsigned long long ;encodedBodySize readonly attribute unsigned long long ;decodedBodySize readonly attribute unsigned short ;responseStatus readonly attribute RenderBlockingStatusType ;renderBlockingStatus readonly attribute DOMString ;contentType readonly attribute DOMString ; [contentEncoding Default ]object (); };toJSON
PerformanceResourceTiming
는 연관된 DOMString인
initiator
type을 가집니다.
PerformanceResourceTiming
는 연관된 DOMString인
delivery
type을 가집니다.
PerformanceResourceTiming
는 연관된 DOMString인
requested
URL을 가집니다.
PerformanceResourceTiming
는 연관된 DOMString인
cache mode
(빈 문자열, "local", 또는 "validated")을 가집니다.
PerformanceResourceTiming
는 연관된 fetch timing info인 timing
info를 가집니다.
PerformanceResourceTiming
는 연관된 response body info인 resource
info를 가집니다.
PerformanceResourceTiming
는 연관된
status인
response status를 가집니다.
PerformanceResourceTiming
는 연관된
RenderBlockingStatusType
인 render-blocking status를 가집니다.
toJSON가 호출되면, 기본
toJSON 단계를 PerformanceResourceTiming에
대해 실행합니다.
initiatorType 게터 단계는 initiator type을 이 객체(this)에 대해 반환하도록 합니다.
initiatorType은 다음 값 중 하나를 반환합니다:
-
"navigation", 요청이 navigation request인 경우; -
"body", 요청이 이미 폐기되었지만 본문 요소의background속성을 처리한 결과인 경우. -
"css", 요청이@import url()또는background: url()과 같은 CSS url() 지시문을 처리한 결과인 경우; [CSS-VALUES]참고: CSS의
@font-face로 지정된 폰트 리소스에 대한 요청은 CSS 지시문 처리의 결과입니다. 따라서 이 폰트 리소스의initiatorType은"css"입니다. -
"script", 요청이 어떤 스크립트를 로드한 결과인 경우(고전 스크립트, 모듈 스크립트 또는Worker). -
"xmlhttprequest", 요청이XMLHttpRequest를 처리한 결과인 경우; -
"font", 요청이 폰트 처리를 통해 발생한 경우. 예를 들어 Incremental Font Transfer가 사용되는 경우 폰트가 후속 리소스를 요청할 수 있습니다. [INCREMENTAL_FONT_TRANSFER] -
"fetch", 요청이fetch()호출의 결과인 경우; -
"beacon", 요청이sendBeacon()호출의 결과인 경우; [BEACON] -
"video", 요청이video요소의poster또는src를 처리한 결과인 경우. -
"audio", 요청이audio요소의src를 처리한 결과인 경우. -
"track", 요청이track요소의src를 처리한 결과인 경우. -
"img", 요청이img요소의src또는srcset를 처리한 결과인 경우. -
"image", 요청이 image 요소를 처리한 결과인 경우. [SVG2] -
"input", 요청이input요소의type이 이미지 버튼(image)인 경우. -
"ping", 요청이a요소의ping를 처리한 결과인 경우. -
"iframe", 요청이iframe의src를 처리한 결과인 경우. -
"frame", 요청이frame를 로드한 결과인 경우. -
"embed", 요청이embed요소의src를 처리한 결과인 경우. -
"link", 요청이link요소를 처리한 결과인 경우. -
"object", 요청이object요소를 처리한 결과인 경우. -
"early-hints", 요청이 [EARLY_HINTS] 응답의 Early Hints를 처리한 결과인 경우. -
"other", 위의 어떤 조건도 해당되지 않는 경우.
initiatorType의 설정은 리소스 타이밍 항목이 보고되는 여러 장소(예: fetch 표준)에서
이루어집니다.
deliveryType 게터 단계는 이 객체(this)에 대한 delivery type을 반환하도록 합니다.
deliveryType은 다음 값 중 하나를 반환합니다:
-
"cache", cache mode가 빈 문자열이 아닌 경우. - 위의 어떤 것도 해당되지 않으면 빈 문자열
"".
이는 향후 이 명세의 업데이트에 의해 확장될 예정입니다. 예: 사전 로드된 리소스 소비나 프리페치된 내비게이션 요청 설명 등.
workerStart getter 단계는 가져오기 타임스탬프 변환을 this의 timing info의 최종 서비스 워커 시작 시간과 해당 글로벌 객체를 this에 대해 수행한다. 자세한 내용은 HTTP fetch를 참조.
redirectStart getter 단계는 가져오기 타임스탬프 변환을 this의 timing info의 리다이렉트 시작 시간과 해당 글로벌 객체를 this에 대해 수행한다. 자세한 내용은 HTTP-redirect fetch를 참조.
redirectEnd getter 단계는 가져오기 타임스탬프 변환을 this의 timing info의 리다이렉트 종료 시간과 해당 글로벌 객체를 this에 대해 수행한다. 자세한 내용은 HTTP-redirect fetch를 참조.
fetchStart getter 단계는 가져오기 타임스탬프 변환을 this의 timing info의 리다이렉트 후 시작 시간과 해당 글로벌 객체를 this에 대해 수행한다. 자세한 내용은 HTTP fetch를 참조.
domainLookupStart getter 단계는 가져오기 타임스탬프 변환을 this의 timing info의 최종 연결 타이밍 정보의 도메인 조회 시작 시간과 해당 글로벌 객체를 this에 대해 수행한다. 자세한 내용은 연결 타이밍 정보 기록를 참조.
domainLookupEnd getter 단계는 가져오기 타임스탬프 변환을 this의 timing info의 최종 연결 타이밍 정보의 도메인 조회 종료 시간과 해당 글로벌 객체를 this에 대해 수행한다. 자세한 내용은 연결 타이밍 정보 기록를 참조.
connectStart getter 단계는 가져오기 타임스탬프 변환을 this의 timing info의 최종 연결 타이밍 정보의 연결 시작 시간과 해당 글로벌 객체를 this에 대해 수행한다. 자세한 내용은 연결 타이밍 정보 기록를 참조.
connectEnd getter 단계는 가져오기 타임스탬프 변환을 this의 timing info의 최종 연결 타이밍 정보의 연결 종료 시간과 해당 글로벌 객체를 this에 대해 수행한다. 자세한 내용은 연결 타이밍 정보 기록를 참조.
secureConnectionStart getter 단계는 가져오기 타임스탬프 변환을 this의 timing info의 최종 연결 타이밍 정보의 보안 연결 시작 시간과 해당 글로벌 객체를 this에 대해 수행한다. 자세한 내용은 연결 타이밍 정보 기록를 참조.
nextHopProtocol getter 단계는 isomorphic decode를 this의 timing info의 최종 연결 타이밍 정보의 ALPN 협상 프로토콜에 대해 수행한다. 자세한 내용은 연결 타이밍 정보 기록를 참조.
Issue 221은 nextHopProtocol 지원을 제거할 것을 제안하는데, 이는 사용자의 네트워크 구성 정보를 노출할 수 있기 때문이다.
requestStart getter 단계는 가져오기 타임스탬프 변환을 this의 timing info의 최종 네트워크 요청 시작 시간과 해당 글로벌 객체를 this에 대해 수행한다. 자세한 내용은 HTTP fetch를 참조.
firstInterimResponseStart getter 단계는 가져오기 타임스탬프 변환을 this의 timing info의 첫 번째 임시 네트워크 응답 시작 시간과 해당 글로벌 객체를 this에 대해 수행한다. 자세한 내용은 HTTP fetch를 참조.
finalResponseHeadersStart getter 단계는 가져오기 타임스탬프 변환을 this의 timing info의 최종 네트워크 응답 시작 시간과 해당 글로벌 객체를 this에 대해 수행한다. 자세한 내용은 HTTP fetch를 참조.
responseStart getter 단계는
this의
firstInterimResponseStart
가 0이 아니면 해당 값을 반환한다;
아니면 this의
finalResponseHeadersStart
값을 반환한다.
responseEnd getter 단계는 가져오기 타임스탬프 변환을 this의 timing info의 종료 시간과 해당 글로벌 객체를 this에 대해 수행한다. 자세한 내용은 fetch를 참조.
encodedBodySize getter 단계는 this의 resource info의 인코딩된 크기를 반환한다.
decodedBodySize getter 단계는 this의 resource info의 디코딩된 크기를 반환한다.
transferSize getter 단계는:
-
이 객체(this)의 cache mode가 "
local"이면 0을 반환합니다. -
이 객체(this)의 cache mode가 "
validated"이면 300을 반환합니다. -
이 객체(this)의 resource info의 encoded size에 300을 더한 값을 반환합니다.
transferSize에 더해지는 상수는 HTTP 헤더의 전체 바이트 크기를 노출하는 대신 사용됩니다. 헤더를 노출하면 특정 쿠키의 존재를 드러낼 수 있기 때문입니다. 자세한 내용은 이 이슈를 참조하십시오.
responseStatus 게터 단계는 이 객체(this)의 response status를 반환하도록 합니다.
responseStatus는 Fetch에서
결정됩니다. 교차 출처의 no-cors 요청의 경우
응답이 opaque filtered
response가 되어 0이 됩니다.
contentType 게터 단계는 이 객체(this)의 resource info의 content type을 반환하도록 합니다.
contentEncoding 게터 단계는 이 객체(this)의 resource info의 content encoding을 반환하도록 합니다.
renderBlockingStatus 게터 단계는 이 객체(this)의 timing info의 render-blocking이 true이면 blocking을 반환하고; 그렇지 않으면 non-blocking을 반환합니다.
workerRouterEvaluationStart 게터 단계는 이 객체(this)의 timing info의 service worker timing info의 worker router evaluation start를 반환하도록 합니다.
workerCacheLookupStart 게터 단계는 이 객체(this)의 timing info의 service worker timing info의 worker cache lookup start를 반환하도록 합니다.
workerMatchedRouterSource 게터 단계는 이 객체(this)의 timing info의 service worker timing info의 worker matched router source를 반환하도록 합니다.
workerFinalRouterSource 게터 단계는 이 객체(this)의 timing info의 service worker timing info의 worker final router source를 반환하도록 합니다.
PerformanceResourceTiming
를 구현하는 사용자 에이전트는 "resource"를 supportedEntryTypes에
포함해야 합니다.
이를 통해 개발자들은 Resource Timing 지원 여부를 감지할 수 있습니다.
3.3.1. RenderBlockingStatusType 열거형
enum {RenderBlockingStatusType ,"blocking" };"non-blocking"
값의 정의는 다음과 같습니다:
- blocking
- 해당 리소스는 잠재적으로 렌더링을 차단할 수 있습니다.
- non-blocking
- 해당 리소스는 렌더링을 차단하지 않습니다.
3.4.
Performance 인터페이스의 확장
사용자 에이전트는 PerformanceResourceTiming
객체로 Performance Timeline에 포함되는 리소스 수를 제한하도록 선택할 수 있습니다.
이 절은 저장되는 PerformanceResourceTiming
객체의 수를 제어하기 위해 Performance 인터페이스를
확장합니다.
권장 최소 PerformanceResourceTiming
객체 수는 250개이며, 사용자 에이전트에 의해 변경될 수 있습니다.
setResourceTimingBufferSize는 이 제한 변경을
요청하기 위해 호출될 수 있습니다.
각 ECMAScript 글로벌 환경은 다음을 가집니다:
- A resource timing buffer size limit 은 초기값이 250 이상이어야 합니다.
- A resource timing buffer current size 은 초기값이 0입니다.
- A resource timing buffer full event pending flag 은 초기값이 false입니다.
- A resource timing secondary buffer current size 은 초기값이 0입니다.
- A resource timing secondary buffer 는
PerformanceResourceTiming객체를 저장하기 위한 보조 버퍼로 초기에는 비어 있습니다.
partial interface Performance {undefined ();clearResourceTimings undefined (setResourceTimingBufferSize unsigned long );maxSize attribute EventHandler ; };onresourcetimingbufferfull
Performance 인터페이스는 [HR-TIME]에서 정의되어 있습니다.
clearResourceTimings 메서드는 다음 단계를 실행합니다:
- Performance entry buffer에 있는 모든
PerformanceResourceTiming객체를 제거합니다. - resource timing buffer current size를 0으로 설정합니다.
setResourceTimingBufferSize 메서드는 다음 단계를 실행합니다:
- resource timing buffer size limit을 maxSize 인수로 설정합니다. maxSize가 현재 resource timing
buffer current size보다 작으면,
performance entry buffer에서 어떤
PerformanceResourceTiming객체도 제거되지 않습니다.
onresourcetimingbufferfull 속성은 아래에 설명된
resourcetimingbufferfull 이벤트에 대한 이벤트 핸들러입니다.
리소스 타이밍 엔트리를 추가할 수 있는지 확인하려면, 다음 단계를 실행한다:
- 리소스 타이밍 버퍼 현재 크기 가 리소스 타이밍 버퍼 크기 제한 보다 작으면, true를 반환한다.
- false 반환.
PerformanceResourceTiming 엔트리 추가를 위해서 new entry 를 퍼포먼스 엔트리 버퍼에 추가하려면, 다음 단계를 실행한다:
-
리소스 타이밍 엔트리를 추가할 수 있는지 가 true를 반환하고,
리소스 타이밍 버퍼 가득참 이벤트
보류 플래그가 false이면,
다음 하위 단계를 실행한다:
- new entry를 퍼포먼스 엔트리 버퍼에 추가한다.
- 리소스 타이밍 버퍼 현재 크기를 1 증가시킨다.
- Return.
-
리소스 타이밍 버퍼 가득참 이벤트
보류 플래그가 false면,
다음 하위 단계를 실행한다:
- 리소스 타이밍 버퍼 가득참 이벤트 보류 플래그를 true로 설정한다.
- 태스크를 큐에 추가한다, 퍼포먼스 타임라인 태스크 소스에서 버퍼 가득참 이벤트 발생을 실행한다.
- new entry를 리소스 타이밍 세컨더리 버퍼에 추가한다.
- 리소스 타이밍 세컨더리 버퍼 현재 크기를 1 증가시킨다.
세컨더리 버퍼 복사를 위해, 다음 단계를 수행한다:
-
리소스 타이밍 세컨더리 버퍼가 비어 있지 않고,
리소스 타이밍 엔트리를 추가할 수 있는지 가 true를 반환하면,
다음 하위 단계를 수행한다:
- entry를 가장 오래된
PerformanceResourceTiming으로 한다, 리소스 타이밍 세컨더리 버퍼에서. - entry를 퍼포먼스 엔트리 버퍼 마지막에 추가한다.
- 리소스 타이밍 버퍼 현재 크기를 1 증가시킨다.
- entry를 리소스 타이밍 세컨더리 버퍼에서 제거한다.
- 리소스 타이밍 세컨더리 버퍼 현재 크기를 1 감소시킨다.
- entry를 가장 오래된
버퍼 가득참 이벤트 발생을 위해, 다음 단계를 수행한다:
-
리소스 타이밍 세컨더리 버퍼가 비어 있지 않으면,
다음 하위 단계를 수행한다:
- number of excess entries before를 리소스 타이밍 세컨더리 버퍼 현재 크기로 한다.
- 리소스 타이밍 엔트리를 추가할 수 있는지 가 false면,
이벤트 발생
resourcetimingbufferfull이름으로,Performance객체에서 한다. - 세컨더리 버퍼 복사를 실행한다.
- number of excess entries after를 리소스 타이밍 세컨더리 버퍼 현재 크기로 한다.
- number of excess entries before가 number of excess entries after 이하이면, 리소스 타이밍 세컨더리 버퍼의 모든 엔트리를 제거하고, 리소스 타이밍 세컨더리 버퍼 현재 크기를 0으로 설정하고, 이 단계들을 중단한다.
-
리소스 타이밍 버퍼 가득참 이벤트
보류 플래그를
false로 설정한다.
이는
resourcetimingbufferfull이벤트 핸들러가 버퍼에 공간을 확보한 것보다 많은 리소스를 추가하면, 초과 엔트리가 버퍼에서 삭제될 수 있음을 의미한다. 개발자는resourcetimingbufferfull이벤트 핸들러에서clearResourceTimings를 호출하거나setResourceTimingBufferSize로 버퍼 크기를 충분히 늘려야 한다.
3.5. 교차 출처 리소스
3.5.1. 소개
Fetch에 자세히 설명된 대로, 교차 출처 리소스에 대한 요청은
PerformanceResourceTiming
객체로 Performance Timeline에 포함됩니다.
만약 교차 출처 리소스에 대해 timing allow
check 알고리즘이 실패하면,
항목은 opaque entry가 됩니다. 이러한 항목들은 교차 출처 데이터를 유출하지
않도록 대부분의 속성이 마스킹됩니다. 따라서 opaque entry의 경우 다음 속성들은 항상 0 또는 빈 문자열을
반환합니다:
redirectStart,
redirectEnd,
workerStart,
domainLookupStart,
domainLookupEnd,
connectStart,
connectEnd,
requestStart,
firstInterimResponseStart,
finalResponseHeadersStart,
responseStart,
secureConnectionStart,
및
nextHopProtocol.
일부 속성들(예: contentType,
encodedBodySize,
및
decodedBodySize)
는 응답이 CORS-교차 출처일 때 0(또는 contentType의 경우 빈 문자열)로 설정됩니다.
transferSize
는 timing allow check 및 CORS-교차 출처 상태 모두의 영향을 받습니다.
서비스 워커가 respondWith()을
사용하여 처리한 요청의 경우,
보고되는 타이밍 데이터는 클라이언트와 서비스 워커 간의 상호작용을 반영하며 서비스 워커 자체의 내부 네트워크 활동을 반영하지 않습니다. 예를 들어 서비스 워커는 동일 출처
요청에 대해 교차 출처 응답을 반환하거나 그 반대로 할 수 있으며, 캐시되거나 합성된 응답을 반환할 수 있습니다. 따라서 서비스 워커에서 전달된 리소스는 리소스 가져오기에
대한 전체 상황을 제공하지 않으며 timing allow check를 거치지 않습니다. 이러한 가져오기들에 대한 전체 정보를 얻으려면 서비스 워커의 자체
performance timeline을 검사해야 합니다.
[SERVICE-WORKERS]
더 자세한 내용은 HTTP
Fetch의 #4를 참조하십시오 — timing allow check는 서비스 워커로부터 응답이 없을 때만 수행됩니다. 또한 response가 respondWith()
알고리즘에서 복제된 경우, 내부 가져오기(fetch)의 fetch timing info는 복제된 response에 포함되지 않습니다. 해당 정보는 response가 아니라
fetch에 첨부됩니다.
3.5.2.
Timing-Allow-Origin 응답 헤더
서버측 애플리케이션은 Timing-Allow-Origin HTTP 응답 헤더를 반환하여, 사용자 에이전트가 교차 출처 제한으로 인해 0이 되었을 속성 값들을 문서 출처에 완전히 노출하도록 허용할 수 있습니다.
Timing-Allow-Origin HTTP 응답 헤더 필드는 허용될 수 있는 출처(origin)를 나타내는 정책을 전달하는 데 사용될 수 있습니다. 헤더 값은 다음 ABNF로 표현됩니다 [RFC5234] (List Extension 및 [RFC9110] 사용):
Timing-Allow-Origin = 1#( origin-or-null / wildcard )
전송자는 여러 개의 Timing-Allow-Origin 헤더 필드를 생성할 수 있습니다. 수신자는 각 후속 필드 값을 쉼표로 구분하여 결합된 필드 값에 덧붙여 여러 개의 Timing-Allow-Origin 헤더 필드를 결합할 수 있습니다.
사용자 에이전트는 여전히 교차 출처 제한을 적용하고 transferSize, encodedBodySize 및 decodedBodySize 속성을 0으로 설정할 수 있습니다. 그럴 경우 deliveryType을 ""로 설정할 수도 있습니다.
Timing-Allow-Origin 헤더는 FETCH에서 처리되어 해당 속성들을 계산합니다.
Timing-Allow-Origin 헤더는 캐시된 응답의 일부로 도착할 수 있습니다. 캐시 재검증의 경우, RFC 7234에 따르면 헤더 값은 재검증 응답에서 올 수도 있고, 거기에 존재하지 않으면 원래의 캐시된 리소스에서 올 수 있습니다.
이슈 222 및 223는 Timing-Allow-Origin에서 와일드카드 지원을 제거하여 사용을 제한할 것을 제안합니다.
3.5.3. IANA 고려사항
이 절은 Timing-Allow-Origin을 임시 메시지 헤더(Provisional Message Header)로 등록합니다.
- 헤더 필드 이름:
-
Timing-Allow-Origin
- 적용 프로토콜:
- http
- 상태:
- provisional
- 작성자/변경 통제:
- W3C
- 명세 문서:
- § 3.5.2 Timing-Allow-Origin 응답 헤더
3.6. 리소스 타이밍 속성
이 절은 비규범적입니다.
다음 도표는 PerformanceResourceTiming 인터페이스에서 정의된 타이밍 속성들을 보여줍니다. 괄호 안의 속성은 교차 출처 리소스를 가져올 때 사용 불가능할 수 있습니다. 사용자 에이전트는 타이밍들 사이에 내부 처리를 수행할 수 있으며, 이는 타이밍 사이에 비규범적 간격을 유발할 수 있습니다.
PerformanceResourceTiming
인터페이스에서 정의된 타이밍 속성들을 보여줍니다. 괄호 안의 속성은 리소스가 timing allow check 알고리즘에 실패한 경우
사용 불가능할 수 있음을 나타냅니다.
4. 리소스 타이밍 항목 생성
리소스 타이밍을 마크(mark resource timing)하려면, 주어진 fetch timing info timingInfo, DOMString requestedURL, DOMString initiatorType, global object global, 문자열 cacheMode, response body info bodyInfo, status responseStatus, 및 선택적 문자열 deliveryType (기본값은 빈 문자열) 을 사용하여 다음 단계를 수행합니다:
- Create a
PerformanceResourceTiming객체 entry를 global의 realm에 생성합니다. - 리소스 타이밍 항목 설정을 수행합니다: entry에 대해 initiatorType, requestedURL, timingInfo, cacheMode, bodyInfo, responseStatus, 및 deliveryType를 사용합니다.
- Queue a PerformanceEntry entry.
- 추가entry를 global의 퍼포먼스 엔트리 버퍼에 추가한다.
리소스 타이밍 항목을 설정하려면,
PerformanceResourceTiming
entry에 대해 DOMString
initiatorType, DOMString requestedURL, fetch timing
info
timingInfo, DOMString cacheMode, response
body info
bodyInfo, status
responseStatus, 및 선택적 DOMString deliveryType (기본값은 빈 문자열)을 사용하여 다음 단계를 수행합니다:
- cacheMode가 빈 문자열(""), "
local", 또는 "validated"인지 확인한다(assert). - global을 entry의 관련 글로벌 객체로 한다.
- 초기화 entry를,
변환한
timingInfo의 시작 시각(global을 기준),
"
resource", requestedURL, 그리고 변환한 timingInfo의 종료 시각(global을 기준)으로 초기화한다. - entry의 initiator type을 initiatorType으로 설정한다.
- entry의 요청된 URL을 requestedURL로 설정한다.
- entry의 timing info를 timingInfo로 설정한다.
- entry의 resource info를 bodyInfo로 설정한다.
- entry의 cache mode를 cacheMode로 설정한다.
- entry의 response status를 responseStatus로 설정한다.
- deliveryType이 빈 문자열이고 cacheMode가 비어 있지 않으면,
deliveryType을 "
cache"로 설정한다. - entry의 delivery type을 deliveryType으로 설정한다.
가져오기 타임스탬프
변환을 하려면,
DOMHighResTimeStamp
ts 및 글로벌 객체 global이 주어졌을 때, 아래를 수행한다:
- ts가 0이면, 0을 반환한다.
- 그 외에는, 상대 고해상도 조잡 시간 (ts와 global 기준)을 반환한다.
5. 보안 고려사항
PerformanceResourceTiming
인터페이스는 리소스에 대한 타이밍 정보를 해당 리소스를 요청한 모든 웹 페이지나 워커에 노출합니다. 이 인터페이스에 대한 접근을 제한하기 위해,
기본적으로 동일 출처(same origin)
정책이 적용되며 특정 속성들은 0으로 설정됩니다.
이는 HTTP fetch에 설명된 바와 같습니다. 리소스 제공자는 Timing-Allow-Origin HTTP 응답
헤더를 추가하여 특정 도메인들이 타이밍 정보를 수집할 수 있도록 명시적으로 허용할 수 있습니다.
6. 개인정보 보호 고려사항
통계적 지문(fingerprinting)은 악의적인 웹사이트가 사용자가 제3자 웹사이트를 방문했는지 여부를 제3자 사이트 리소스의 캐시 적중/미스 타이밍을 측정해 판단할 수 있는 개인정보
문제입니다. PerformanceResourceTiming
인터페이스는 문서 내 리소스에 대한 타이밍 정보를 제공하지만, 리소스에 대한 load 이벤트는 이미 제한된 방식으로 캐시 적중/미스를 판단할 수 있는 타이밍을 측정할 수 있으며, HTTP Fetch의 교차 출처 제한은 추가 정보 유출을 방지합니다.
7. 감사의 글
Anne Van Kesteren, Annie Sullivan, Arvind Jain, Boris Zbarsky, Darin Fisher, Jason Weber, Jonas Sicking, James Simonsen, Karen Anderson, Kyle Scholz, Nic Jansma, Philippe Le Hegaret, Sigbjørn Vik, Steve Souders, Todd Reifsteck, Tony Gentilcore, William Chan, 및 Alex Christensen에게 이 작업에 기여해 주신 것에 감사드립니다.