1. 소개
이 섹션은 비규범적입니다.웹 애플리케이션의 성능 특성을 정확하게 측정하는 것은 웹 애플리케이션을 더 빠르게 만드는 중요한 부분입니다. [NAVIGATION-TIMING]과 [RESOURCE-TIMING]은 문서와 그 리소스에 대한 상세한 요청 타이밍 정보를 제공합니다. 여기에는 요청이 시작된 시간, 그리고 연결 협상 및 응답 수신을 위한 다양한 단계가 포함됩니다. 하지만 사용자 에이전트가 요청의 타이밍 데이터를 관찰할 수 있어도 요청-응답 사이클의 특정 단계가 왜 또는 어떻게 오래 걸렸는지에 대한 내부 정보를 알 수 없습니다. 예를 들어, 요청이 어떻게 라우팅되었는지, 서버에서 시간이 어떻게 쓰였는지 등입니다.
이 명세는 PerformanceServerTiming
인터페이스를 소개하며, 서버가 요청-응답 사이클의 성능 지표를 사용자 에이전트에 전달하고, 애플리케이션이 이러한 지표를 수집·처리·활용하여 앱 전달을 최적화할 수 있도록 하는
JavaScript 인터페이스를 표준화합니다.
2.
Server-Timing 헤더 필드
Server-Timing 헤더 필드는 특정 요청-응답 사이클에 대해 하나 이상의 지표와 설명을 전달하는 데 사용됩니다. [RFC5234]의 ABNF(확장된 Backus-Naur Form) 구문에서 Server-Timing 헤더 필드는 다음과 같이 정의됩니다:
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 항목이 존재할 수 있으며, 사용자 에이전트는 모든 항목을 처리하고 노출해야 합니다.
사용자 에이전트는 제공된 지표를 임의의 순서로 표시할 수 있습니다. 즉, HTTP 헤더 필드 내의 지표 순서는 중요하지 않습니다.
이 헤더 필드는 미래의 파라미터를 허용하기 위해 확장 가능한 구문으로 정의됩니다. 응답의 Server-Timing 헤더 필드에서 특정 server-timing-param-name을 인식하지 못하는 사용자 에이전트는 해당 토큰을 무시하고 오류 신호 없이 계속 처리해야 합니다.
모호성을 피하기 위해, 개별 server-timing-param-name은 server-timing-metric 내에서 여러 번 나타나지 않아야
합니다. 만약 server-timing-param-name이 여러 번 지정되면 첫 번째 인스턴스만 고려하고, server-timing-param가
불완전하거나 유효하지 않더라도 모든 후속 등장들은 오류 신호 없이 무시하며, server-timing-metric 처리에도 영향을 주지 않습니다. 이 경우만
server-timing-metric 내 파라미터의 순서가 의미를 가집니다.
사용자 에이전트는 server-timing-param-value 뒤에서 다음 server-timing-param 및 현재
server-timing-metric의 끝 전까지 발견된 불필요한 문자를 무시해야 합니다.
사용자 에이전트는 metric-name 뒤에서 첫 server-timing-param 및 다음
server-timing-metric 전까지 발견된 불필요한 문자를 무시해야 합니다.
이 명세는 server-timing-param-names로 "dur"(duration)과
"desc"(description)을
정의합니다. 둘 다 선택 사항입니다.
- HTTP 오버헤드를 최소화하려면 제공하는 이름과 설명을 최대한 짧게 해야 합니다. 예를 들어 약어를 사용하고 선택적 값은 가능한 생략하세요.
- 클라이언트, 서버, 그리고 중개자 간에 시간 동기화가 보장되지 않으므로, 클라이언트 타임라인에 의미 있는
startTime을 매핑하는 것은 불가능합니다. 따라서 본 명세에서는startTime속성을 의도적으로 제외합니다. 개발자가 여러 항목 사이의 관계를 수립하려면, metric name 또는 description에 맞춤 데이터를 포함해 직접 전달할 수 있습니다. - 서버 또는 관련 중개자는 사용자 에이전트에 어떤 지표를 언제 전달할지 완전히 제어할 수 있습니다. 예를 들어 프라이버시 또는 보안상의 이유로 일부 지표에 대한 접근이 제한될 수 있습니다. 자세한 내용은 § 4 프라이버시 및 보안 섹션을 참고하세요.
Server-Timing 헤더 필드 파싱 동작은 문자열 field가 주어졌을 때 다음과 같다:
-
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 quoted string 수집 결과로 설정한다, field와 position, 그리고 extract-value flag가 설정된 상태로 수행한다.
-
코드 포인트 시퀀스 수집을 field에서 U+003B(;)가 아닌 문자에 대해 position에서 수행한다. 결과는 사용하지 않는다.
-
-
그 외의 경우:
-
rawParamValue를 코드 포인트 시퀀스 수집 결과로, field에서 U+003B(;)가 아닌 문자들을 position에서 수집한다.
-
paramValue를 공백 제거를 rawParamValue에 대해 수행한 결과로 설정한다.
-
-
-
metric을 반환한다.
3.
PerformanceServerTiming
인터페이스
[Exposed =(Window ,Worker )]interface {PerformanceServerTiming readonly attribute DOMString name ;readonly attribute DOMHighResTimeStamp duration ;readonly attribute DOMString description ; [Default ]object (); };toJSON
toJSON이 호출되면, [WEBIDL]의 기본 toJSON 단계를 실행한다.
3.1. name
속성
name
getter 단계는 this의
metric name을 반환하도록 한다.
3.2. duration 속성
duration
getter 단계는 다음을 수행한다:
-
dur을 this의 params[
"dur"]을 부동 소수점 숫자 값 파싱 규칙을 사용하여 파싱한 결과로 한다. -
dur이 오류이면 0을, 그렇지 않으면 dur을 반환한다.
duration
속성은 DOMHighResTimeStamp이므로,
보통 밀리초 단위의 duration을
나타낸다. 하지만 실제로 강제할 수 없기 때문에, duration
속성은 임의의 시간 단위를 나타낼 수 있으며,
밀리초 단위로 표현하는 것이 권장된다.
3.3.
description 속성
description
getter 단계는 this의
params["desc"]이 존재한다면 반환하고, 그렇지 않으면 빈 문자열을
반환한다.
PerformanceServerTiming
객체는 연관된 문자열 metric name을 가지며, 처음에는 빈 문자열로 설정된다.
PerformanceServerTiming
객체는 연관된 ordered map params를 가지며, 처음에는 비어 있다.
3.4. PerformanceResourceTiming
인터페이스 확장
PerformanceResourceTiming
인터페이스(이 명세가 부분적으로 확장하는)는 [RESOURCE-TIMING]에서 정의된다.
[Exposed =(Window ,Worker )]partial interface PerformanceResourceTiming {readonly attribute FrozenArray <PerformanceServerTiming >serverTiming ; };
3.5.
serverTiming 속성
serverTiming getter 단계는
다음과 같다:
-
entries를 새로운 목록으로 한다.
-
각각의 field에 대하여 this의 timing info의 server-timing headers에서:
-
entries를 반환한다.
4. 프라이버시 및 보안
이 섹션은 비규범적입니다.이 명세에서 정의된 인터페이스는 서버 타이밍 지표를 광고하는 리소스를 포함한 웹 페이지에 잠재적으로 민감한 애플리케이션 및 인프라 정보를 노출할
수 있습니다. 이 때문에 PerformanceServerTiming 인터페이스에 대한 접근은 기본적으로 동일 출처 정책에 의해 제한됩니다. 리소스 제공자는 [RESOURCE-TIMING]에서 정의한
Timing-Allow-Origin HTTP 응답 헤더를 추가하여 특정 도메인에 서버 지표 접근을 명시적으로 허용할 수 있지만, 사용자 에이전트는 동일 출처 정책 제한을 계속 유지할 수 있습니다.
Timing-Allow-Origin HTTP 응답 헤더 외에도 서버는 관련 로직을 통해 어떤 지표를 언제, 누구에게
반환할지 제어할 수 있습니다. 예를 들어, 서버는 특정 메트릭을 인증된 사용자에게만 제공하고, 그 외에는 아무 것도 제공하지 않을 수 있습니다.
5. IANA 고려사항
영구 메시지 헤더 필드 레지스트리는 다음 등록 항목으로 업데이트되어야 합니다 ([RFC3864]):
5.1. Server-Timing 헤더 필드
- 헤더 필드 이름
- Server-Timing
- 적용 프로토콜
- http
- 상태
- standard
- 작성자/변경 컨트롤러
- W3C
- 명세 문서
- 이 명세 (See Server-Timing 헤더 필드)
6. 예시
이 섹션은 비규범적입니다.> 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
| 이름 | 지속 시간 | 설명 |
|---|---|---|
| miss | ||
| db | 53 | |
| app | 47.2 | |
| customView | ||
| dc | atl | |
| cache | 23.2 | Cache Read |
| total | 123.4 |
위 헤더 필드는 서버가 데이터 전달 방식의 모든 사례(지표 이름만, 값이 있는 지표, 값 및 설명이 있는 지표, 설명만 있는 지표)를 보여주는
여섯 가지 구분된 지표를 제공합니다. 예를 들어, 위 지표는 example.com/resource.jpg fetch에 대해 다음을 나타냅니다:
- 캐시 미스가 발생했다.
- 요청이 "atl" 데이터센터("dc")를 경유했다.
- 데이터베이스("db") 시간은 53ms였다.
- 캐시 읽기는 23.2ms 걸렸다.
- 애플리케이션 서버("app")가 "customView" 템플릿이나 기능 처리에 47.2ms를 소요했다.
- 요청-응답 사이클의 서버 총 시간은 123.4ms였다. 이는 응답의 마지막에 trailer 필드로 전달된다.
애플리케이션은 제공된 JavaScript 인터페이스를 통해 지표를 수집, 처리, 활용할 수 있습니다:
// serverTiming 항목은 'navigation'과 'resource' entry에서 사용될 수 있음 for ( const entryTypeof [ 'navigation' , 'resource' ]) { for ( const { name: url, serverTiming} of performance. getEntriesByType( entryType)) { // serverTiming 배열 반복 for ( const { name, duration, description} of serverTiming) { // "느린" 항목만 관심 있음 if ( duration> 200 ) { console. info( '느린 server-timing 항목 =' , JSON. stringify({ url, entryType, name, duration, description}, null , 2 )) } } } }
7. 활용 사례
이 섹션은 비규범적입니다.7.1. 개발자 도구의 서버 타이밍
서버 처리 시간은 전체 요청 시간의 상당한 부분을 차지할 수 있습니다. 예를 들어, 동적 응답은 하나 이상의 데이터베이스 쿼리, 캐시 조회, API 호출, 관련 데이터 처리 및 응답 렌더링 등 여러 단계가 필요할 수 있습니다. 또한 정적 응답도 서버 과부하, 느린 캐시 등의 이유로 지연될 수 있습니다.
현재 사용자 에이전트 개발자 도구는 요청이 언제 시작되고 응답의 첫 바이트와 마지막 바이트를 언제 받았는지 보여줄 수 있습니다. 하지만 서버에서 시간이 어디에 어떻게 소비되었는지 볼 수 없으므로, 개발자가 서버에 성능 병목이 있는지, 있다면 어떤 구성 요소에서 발생했는지 빠르게 진단할 수 없습니다. 현재 이 문제를 해결하려면 개발자는 서버 로그 확인, 응답 내용에 성능 데이터 포함(가능한 경우), 외부 도구 사용 등이 필요합니다. 이러한 절차는 성능 병목 진단을 어렵게 하며, 실질적으로 비현실적인 경우가 많습니다.
서버 타이밍은 서버가 클라이언트에 관련 성능 지표를 전달할 수 있게 하는 표준 메커니즘을 정의하며, 클라이언트는 이를 개발자 도구에서 직접 노출할 수 있습니다. 즉, 요청에 서버가 제공한 지표가 주석으로 붙어 응답 생성 중 어디에 어떻게 시간이 소비되었는지 알 수 있습니다.
7.2. 자동화 분석을 위한 서버 타이밍
서버가 보낸 성능 지표를 개발자 도구에 노출하는 것 외에도 표준 JavaScript 인터페이스를 통해 분석 도구가 자동으로 지표를 수집, 처리, 비콘, 집계하여 운영 및 성능 분석에 활용할 수 있습니다.
7.3. 요청 라우팅 성능 측정
서버 타이밍은 원본 서버가 요청 처리 중 어디에서, 어떻게 시간이 소비되었는지에 대한 성능 지표를 전달할 수 있게 해줍니다. 하지만 동일한 요청과 응답이 하나 이상의 여러 프록시(예: 캐시 서버, 로드 밸런서 등)를 경유할 수도 있는데, 각 프록시는 자체 지연을 유발할 수 있으며 시간 소비에 대한 자체 성능 지표를 함께 제공하고 싶을 수 있습니다.
예를 들어, CDN 엣지 노드는 어느 데이터센터를 사용했는지, 리소스가 캐시에 있었는지, 캐시 혹은 원본 서버에서 응답을 받는 데 걸린 시간을 보고하고 싶을 수 있습니다. 또한 다른 프록시들도 동일한 작업을 반복할 수 있어 전체 요청의 경로와 시간 사용에 대한 완전한 엔드-투-엔드 가시성을 제공합니다.
마찬가지로 서비스 워커가 활성화된 경우 탐색 및 리소스 요청의 일부 또는 전부가 이를 경유할 수 있습니다. 실제로 활성화된 서비스 워커는 로컬 프록시로 요청을 재경로하고, 캐시된 응답을 제공하거나 응답을 합성할 수 있습니다. 결과적으로 서버 타이밍은 서비스 워커가 요청 처리 방식(예: 서버 fetch 또는 로컬 캐시 제공, 각 단계의 소요 시간 등)에 대한 맞춤 성능 지표를 보고할 수 있게 해줍니다.
8. 감사의 글
이 섹션은 비규범적입니다.이 문서는 [NAVIGATION-TIMING], [RESOURCE-TIMING], [PERFORMANCE-TIMELINE-2], [RFC6797] 명세의 텍스트를 라이선스가 허용하는 범위 내에서 재사용합니다.