Copyright © 2023 World Wide Web Consortium. W3C® liability, trademark and permissive document license rules apply.
이 명세는 서버가 요청-응답 사이클에 대한 성능 지표를 사용자 에이전트에 전달할 수 있도록 합니다. 또한 애플리케이션이 이러한 지표를 수집, 처리 및 활용하여 애플리케이션 제공을 최적화할 수 있도록 자바스크립트 인터페이스를 표준화합니다.
이 섹션은 이 문서가 발행될 당시의 상태를 설명합니다. 최신 W3C 발행물 목록과 이 기술 보고서의 최신 개정본은 W3C 기술 보고서 색인에서 확인할 수 있습니다: https://www.w3.org/TR/.
이 문서는 웹 성능 워킹 그룹에서 권고 트랙을 통해 작업 초안으로 발행되었습니다.
작업 초안으로 발행되었다고 해서 W3C 및 회원사의 지지를 의미하지는 않습니다.
이 문서는 초안 문서로, 언제든지 업데이트, 교체 또는 폐기될 수 있습니다. 진행 중인 작업 외에는 인용에 부적합합니다.
이 문서는 W3C 특허 정책에 따라 운영되는 그룹에 의해 작성되었습니다. W3C는 공개 특허 공개 목록을 관리하며, 해당 그룹의 산출물과 관련된 특허 공개 내역을 제공합니다. 해당 페이지에는 특허 공개 방법에 대한 안내도 포함되어 있습니다. 어떤 개인이 필수 청구항이 있다고 판단하는 특허를 실제로 알고 있다면, W3C 특허 정책 6절에 따라 정보를 공개해야 합니다.
이 문서는 2021년 11월 2일 W3C 프로세스 문서에 따라 관리됩니다.
이 섹션은 비규범적입니다.
웹 애플리케이션의 성능 특성을 정확하게 측정하는 것은 웹 애플리케이션을 더 빠르게 만드는 데 중요한 요소입니다. [NAVIGATION-TIMING]과 [RESOURCE-TIMING]은 문서 및 리소스에 대한 요청 타이밍 정보를 자세히 제공하며, 여기에는 요청이 시작된 시점과 연결 협상 및 응답 수신까지의 다양한 마일스톤이 포함됩니다. 하지만 사용자 에이전트가 요청의 타이밍 데이터는 관찰할 수 있어도, 요청-응답 사이클의 특정 단계가 왜, 어떻게 그렇게 많은 시간이 소요되었는지에 대한 인사이트는 없습니다. 예를 들어, 요청이 어떻게 라우팅되었는지, 서버에서 시간이 어디에 소비되었는지 등입니다.
이 명세는 서버가 요청-응답 사이클에 대한 성능 지표를 사용자 에이전트에 전달할 수 있도록 하는 PerformanceServerTiming
인터페이스와, 애플리케이션이 이러한
지표를 수집, 처리 및 활용하여 애플리케이션 제공을 최적화할 수 있도록 하는 자바스크립트 인터페이스를 도입합니다.
비규범적으로 표시된 섹션뿐만 아니라, 이 명세서의 모든 저작 지침, 도표, 예시, 참고 사항도 비규범적입니다. 그 외의 모든 내용은 규범적입니다.
이 문서에서 MAY, MUST, SHOULD NOT과 같은 핵심 용어는 BCP 14 [RFC2119] [RFC8174] 에서 설명된 대로 해석되어야 하며, 이러한 용어가 모두 대문자로 표시될 때만 적용됩니다.
Server-Timing 헤더 필드는 해당 요청-응답 사이클에 대한 하나 이상의 메트릭과 설명을 전달하는 데 사용됩니다. RFC5234에서 정의된 ABNF(확장된 바커스-나우어 형식) 문법은 다음과 같습니다:
Server-Timing = #server-timing-metric
server-timing-metric = metric-name *( OWS ";" OWS server-timing-param )
metric-name = token
server-timing-param = server-timing-param-name OWS "=" OWS server-timing-param-value
server-timing-param-name = token
server-timing-param-value = token / quoted-string
RFC7230에서 #
,
*
, OWS
, token
, quoted-string
에 대한 정의를 참고하세요.
응답에는 동일한 metric-name을 갖는 server-timing-metric 항목이 여러 개 있을 수 있으며(MAY), 사용자 에이전트는 이러한 모든 항목을 처리 및 노출해야 합니다(MUST).
사용자 에이전트는 제공된 메트릭을 임의의 순서로 노출할 수 있습니다(MAY)—즉, HTTP 헤더 필드에서의 메트릭 순서는 중요하지 않습니다.
이 헤더 필드는 향후 파라미터를 위해 확장 가능한 문법으로 정의되었습니다. 응답의 Server-Timing 헤더 필드에 인식할 수 없는 server-timing-param-name이 있으면, 사용자 에이전트는 해당 토큰을 무시하고 오류 신호 없이 계속 처리해야 합니다(MUST).
모호성을 방지하기 위해, 각 server-timing-param-name
은 하나의 server-timing-metric
내에서 한 번만 나타나야
합니다(SHOULD NOT). 동일한 이름이 여러 번 지정되면, 첫 번째 인스턴스만 고려되며, 이후의 모든 인스턴스는 오류 신호 없이 무시되어야
합니다(MUST). 이 경우에만 server-timing-metric
내에서 파라미터의 순서가 중요합니다.
사용자 에이전트는 server-timing-param-value
뒤에서 다음 server-timing-param
이나 현재
server-timing-metric
의 끝 이전에 발견된 불필요한 문자를 무시해야 합니다(MUST).
사용자 에이전트는 metric-name
뒤에서 첫 번째 server-timing-param
이나 다음
server-timing-metric
이전에 발견된 불필요한 문자를 무시해야 합니다(MUST).
이 명세는 server-timing-param-names "dur"(duration
)과 "desc"(description
)을
server-timing-params로 규정하며, 둘 다 선택적입니다.
HTTP 오버헤드를 최소화하기 위해 제공되는 이름과 설명은 가능한 한 짧게 유지해야 합니다—예를 들어, 약어를 사용하고 선택적 값은 가능하면 생략하세요.
클라이언트, 서버, 중계기 간의 시계 동기화가 보장될 수 없으므로, 클라이언트 타임라인에 의미 있는 startTime
을 매핑하는 것은
불가능합니다. 따라서 이 명세에서는 startTime
속성을 일부러 포함하지 않습니다. 여러 항목 간의 관계를 개발자가 설정하고 싶다면,
메트릭 이름이나 설명을 통해 사용자 정의 데이터를 전달하여 구현할 수 있습니다.
서버 및 관련 중계기는 어떤 메트릭을 언제 사용자 에이전트에 전달할지 완전히 제어할 수 있습니다. 예를 들어, 일부 메트릭은 프라이버시 또는 보안상의 이유로 제한될 수 있습니다—6. 프라이버시 및 보안 섹션 참고.
서버 타이밍 헤더 필드 파싱 알고리즘은 문자열 field가 주어졌을 때 다음과 같이 동작합니다:
position을 position 변수로, field의 시작을 가리키도록 설정합니다.
name을 시퀀스 코드 포인트 수집을 field에서 U+003B(;)가 아닌 값에 대해, position을 기준으로 실행한 결과로 설정합니다.
ASCII 공백 앞뒤 제거를 name에 적용합니다.
name이 빈 문자열이면 null을 반환합니다.
metric을 새로운 PerformanceServerTiming
로 생성하고, metric name을 name으로 설정합니다.
params를 빈 순서가 지정된 맵으로 설정합니다.
position이 field의 끝에 도달하지 않은 동안:
position을 1 증가시킵니다.
paramName을 시퀀스 코드 포인트 수집을 field에서 U+003D(=)가 아닌 값에 대해, position을 기준으로 실행한 결과로 설정합니다.
ASCII 공백 앞뒤 제거를 paramName에 적용합니다.
position을 1 증가시킵니다.
paramValue를 빈 문자열로 설정합니다.
ASCII 공백 건너뛰기를 field에서 position 기준으로 실행합니다.
field의 position 위치에 있는 코드 포인트가 U+0022(")이면:
paramValue를 HTTP 쿼티드 스트링 수집을 field에서 position 기준으로, extract-value flag를 설정하여 실행한 결과로 설정합니다.
시퀀스 코드 포인트 수집을 field에서 U+003B(;)가 아닌 값에 대해, position 기준으로 실행합니다(결과는 사용하지 않음).
그 외의 경우:
rawParamValue를 시퀀스 코드 포인트 수집을 field에서 U+003B(;)가 아닌 값에 대해, position 기준으로 실행한 결과로 설정합니다.
paramValue를 앞뒤 ASCII 공백 제거를 rawParamValue에 적용한 결과로 설정합니다.
metric을 반환합니다.
WebIDL[Exposed=(Window,Worker)]
interface PerformanceServerTiming
{
readonly attribute DOMString name
;
readonly attribute DOMHighResTimeStamp duration
;
readonly attribute DOMString description
;
[Default] object toJSON
();
};
toJSON
가 호출되면, [WEBIDL]의 default
toJSON steps를 실행합니다.
name
getter 단계는 this의 metric name을 반환하는 것입니다.
duration
getter 단계는 다음과 같습니다:
dur을 this의 params["dur"
]을 부동
소수점 숫자 값 파싱 규칙으로 파싱한 결과로 설정합니다.
dur이 오류이면 0을 반환하고, 그렇지 않으면 dur을 반환합니다.
duration
은 DOMHighResTimeStamp
이므로,
일반적으로 밀리초 단위의 duration을 나타냅니다. 하지만 실제로 이를 강제할 수 없으므로,
duration
은 임의의 시간 단위를 나타낼 수
있습니다. 밀리초 단위로 표현하는 것이 권장 사항입니다.
description
getter 단계는 this의 params["desc"
]가 존재하면 해당 값을, 그렇지 않으면 빈 문자열을 반환합니다.
PerformanceServerTiming
은 문자열 metric name을
연관하며, 초기값은 빈 문자열입니다.
PerformanceServerTiming
은 순서가 지정된 맵 params를 연관하며, 초기값은 비어 있습니다.
PerformanceResourceTiming
인터페이스 확장PerformanceResourceTiming
인터페이스(이 명세가 부분적으로 확장함)는 [RESOURCE-TIMING]에서 정의됩니다.
WebIDL[Exposed=(Window,Worker)]
partial interface PerformanceResourceTiming
{
readonly attribute FrozenArray<PerformanceServerTiming
> serverTiming
;
};
serverTiming
getter 단계는 다음과 같습니다:
entries를 새로운 리스트로 설정합니다.
각 field에 대해 this의 timing info의 server-timing headers에서:
metric을 서버 타이밍 헤더 필드 파싱을 field로 실행한 결과로 설정합니다.
metric이 null이 아니면, append를 통해 metric을 entries에 추가합니다.
entries를 반환합니다.
이 섹션은 비규범적입니다.
이 명세에서 정의된 인터페이스는 서버 타이밍 메트릭을 광고하는 리소스를 포함한 모든 웹 페이지에 잠재적으로 민감한 애플리케이션 및 인프라 정보를 노출합니다. 이러한 이유로
PerformanceServerTiming
인터페이스에 대한 접근은 기본적으로 동일 출처 정책으로 제한됩니다. 리소스 제공자는
HTTP 응답 헤더 Timing-Allow-Origin
을 추가하여 서버 타이밍 정보의 접근 가능 출처를 명시적으로 허용할 수 있습니다([RESOURCE-TIMING] 참고). 이때 사용자 에이전트는 MAY
동일 출처 정책 제한을 유지할 수 있습니다.
HTTP 응답 헤더 Timing-Allow-Origin
을 사용하는 것 외에도, 서버는 어떤 메트릭을 언제, 누구에게 반환할지 제어하는 로직을 사용할 수 있습니다. 예를
들어, 서버는 인증된 사용자에게만 특정 메트릭을 제공하고 다른 사용자에게는 아무런 정보를 제공하지 않을 수 있습니다.
영구 메시지 헤더 필드 등록부는 아래 등록 정보로 업데이트되어야 합니다 ([RFC3864] 참고):
이 섹션은 비규범적입니다.
> GET /resource HTTP/1.1
> Host: example.com
< HTTP/1.1 200 OK
< Server-Timing: miss, db;dur=53, app;dur=47.2
< Server-Timing: customView, dc;desc=atl
< Server-Timing: cache;desc="Cache Read";dur=23.2
< Trailer: Server-Timing
< (... snip response body ...)
< Server-Timing: total;dur=123.4
이름 | Duration | 설명 |
---|---|---|
miss | ||
db | 53 | |
app | 47.2 | |
customView | ||
dc | atl | |
cache | 23.2 | Cache Read |
total | 123.4 |
위 헤더 필드는 서버가 사용자 에이전트에 데이터를 전달하는 모든 가능한 방법을 보여주는 6개의 개별 메트릭을 전달합니다: 메트릭 이름만 있는 경우, 값이 있는 경우, 값과 설명이 모두 있는 경우,
설명만 있는 경우 등. 예를 들어, 위의 메트릭들은 example.com/resource.jpg
fetch에 대해 다음을 나타냅니다:
애플리케이션은 제공된 JavaScript 인터페이스를 통해 메트릭을 수집, 처리, 활용할 수 있습니다:
// serverTiming 항목은 'navigation'과 'resource' 항목에 존재할 수 있음
for (const entryType of ['navigation', 'resource']) {
for (const {name: url, serverTiming} of performance.getEntriesByType(entryType)) {
// serverTiming 배열을 순회
for (const {name, duration, description} of serverTiming) {
// 느린 항목만 관심 있음
if (duration > 200) {
console.info('Slow server-timing entry =',
JSON.stringify({url, entryType, name, duration, description}, null, 2))
}
}
}
}
이 섹션은 비규범적입니다.
서버 처리 시간은 전체 요청 시간에서 상당한 비중을 차지할 수 있습니다. 예를 들어, 동적 응답의 경우 하나 이상의 데이터베이스 쿼리, 캐시 조회, API 호출, 관련 데이터 처리 및 응답 렌더링 등의 과정이 필요할 수 있습니다. 마찬가지로 정적 응답이라도 서버 과부하, 느린 캐시 등 다양한 이유로 지연될 수 있습니다.
현재 사용자 에이전트 개발자 도구에서는 요청이 시작된 시점과 응답의 첫 바이트/마지막 바이트가 수신된 시점을 보여줄 수 있습니다. 하지만 서버에서 시간이 어디에, 어떻게 사용되었는지에 대한 가시성은 없습니다. 즉, 개발자는 서버에 성능 병목이 있는지, 있다면 어떤 구성 요소에 있는지 빠르게 진단할 수 없습니다. 현재 이를 확인하려면 개발자는 서버 로그를 확인하거나, 응답 내에 성능 데이터를 삽입하거나(가능할 경우), 외부 도구를 사용하는 등 다양한 방법을 사용해야 합니다. 이는 병목 식별 및 진단을 어렵게 하며, 실무적으로도 매우 불편합니다.
서버 타이밍은 서버가 관련 성능 메트릭을 클라이언트에 전달하고, 클라이언트가 이를 개발자 도구에 직접 노출할 수 있게 하는 표준 메커니즘을 정의합니다. 즉, 요청에 서버에서 전송한 메트릭을 주석으로 추가하여 응답 생성 과정에서 시간이 어디에, 어떻게 소비되었는지 인사이트를 제공합니다.
개발자 도구에 서버에서 전송된 성능 메트릭을 노출하는 것 외에도, 표준 자바스크립트 인터페이스를 통해 분석 도구가 이러한 메트릭을 자동으로 수집, 처리, 비콘, 집계하여 운영 및 성능 분석에 활용할 수 있습니다.
서버 타이밍은 오리진 서버가 요청 처리 중 어디에서, 어떻게 시간이 소비되었는지에 대한 성능 메트릭을 전달할 수 있게 합니다. 하지만 동일한 요청과 응답이 하나 이상의 프록시(예: 캐시 서버, 로드 밸런서 등)를 거칠 수 있는데, 각각이 자체 지연을 유발할 수 있고, 시간 소비에 대한 성능 메트릭을 제공할 수 있습니다.
예를 들어, CDN 엣지 노드는 어떤 데이터센터가 사용되었는지, 리소스가 캐시에 있었는지, 캐시나 오리진 서버에서 응답을 가져오는데 걸린 시간 등을 보고할 수 있습니다. 또한, 동일한 과정이 여러 프록시에서 반복될 수 있으므로, 요청이 어떻게 라우팅되고 시간 소비가 어디서 발생했는지 전체 엔드투엔드 가시성을 제공합니다.
마찬가지로 Service Worker가 활성화된 경우 탐색 및 리소스 요청 일부 또는 전체가 이를 통해 라우팅될 수 있습니다. Service Worker는 요청을 재라우팅하거나, 캐시된 응답을 제공하거나, 응답을 합성하는 등 로컬 프록시 역할을 할 수 있습니다. 결과적으로 서버 타이밍은 Service Worker가 요청을 어떻게 처리했는지, 서버에서 받아왔는지 또는 로컬 캐시에서 제공했는지, 처리 단계별 소요 시간 등 맞춤형 성능 메트릭을 보고할 수 있게 합니다.
이 섹션은 비규범적입니다.
이 문서는 [NAVIGATION-TIMING]·[RESOURCE-TIMING]·[PERFORMANCE-TIMELINE-2]·[RFC6797] 명세의 텍스트를 해당 명세 라이선스에 따라 재사용합니다.
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in: