サーバータイミング

W3C作業草案

この文書の詳細情報
このバージョン:
https://www.w3.org/TR/2023/WD-server-timing-20230411/
最新公開バージョン:
https://www.w3.org/TR/server-timing/
最新編集者ドラフト:
https://w3c.github.io/server-timing/
履歴:
https://www.w3.org/standards/history/server-timing
コミット履歴
編集者:
(Akamai)
Ilya Grigorik (Google)
フィードバック:
GitHub w3c/server-timing (プルリクエスト, 新規イシュー, オープンイシュー)
public-web-perf@w3.org 件名 [server-timing] (アーカイブ)
メーリングリスト
public-web-perf@w3.org
実装
テストスイート
テストスイートリポジトリ

概要

この仕様は、サーバーがリクエスト-レスポンスサイクルに関するパフォーマンス指標をユーザーエージェントに通知できるようにします。また、アプリケーションがこれらの指標を収集・処理・活用して、アプリケーションの配信を最適化できるようにするJavaScriptインターフェースも標準化します。

この文書のステータス

このセクションは、公開時点での 文書のステータスを説明しています。現行のW3C 公開物と技術レポートの最新版は、 W3C 技術レポート一覧(https://www.w3.org/TR/)で参照できます。

この文書は、Webパフォーマンス作業グループによって 勧告トラックを利用して作業草案として公開されました。

作業草案としての公開は、W3Cおよびそのメンバーによる承認を意味するものではありません。

この文書はドラフトであり、いつでも更新・置換または廃止される可能性があります。他の文書として引用するのは不適切です。進行中の作業としてのみ引用してください。

この文書は、 W3C 特許ポリシーの下で活動するグループによって作成されました。 W3Cは、 関連する特許開示の公開リストを 管理しています。グループの成果物に関連する特許開示は、そのページで確認でき、特許開示の手順も記載されています。個人が、本質的なクレームを含む特許について実際に知識がある場合は、 W3C特許ポリシー第6節に従って情報を開示しなければなりません。

この文書は、 2021年11月2日版 W3Cプロセス文書に従って管理されています。

1. はじめに

このセクションは非規定(参考)です。

Webアプリケーションのパフォーマンス特性を正確に測定することは、Webアプリケーションを高速化するための重要な側面です。 [NAVIGATION-TIMING] および [RESOURCE-TIMING] は、ドキュメントとそのリソースに対する詳細なリクエストタイミング情報を提供します。これにはリクエストが開始された時刻や、接続のネゴシエーションやレスポンスの受信などの様々なマイルストーンが含まれます。しかし、ユーザーエージェントはリクエストのタイミングデータを観測できるものの、リクエスト-レスポンスサイクルの特定の段階がなぜ、あるいはどのようにしてそれだけの時間がかかったのかについては把握できません。例えば、リクエストがどのようにルーティングされたか、サーバー側でどこに時間が費やされたかなどです。

この仕様では、PerformanceServerTimingインターフェースを導入します。これにより、サーバーはリクエスト-レスポンスサイクルに関するパフォーマンス指標をユーザーエージェントに通知でき、アプリケーションがこれらの指標を収集、処理、活用してアプリケーションの配信を最適化できるJavaScriptインターフェースも提供します。

2. 適合性

非規定と記載されているセクションだけでなく、この仕様書内のすべての作成ガイドライン、図、例、および注記は非規定です。それ以外の内容はすべて規定です。

この文書におけるキーワード MAYMUSTSHOULD NOT は、 BCP 14 [RFC2119] [RFC8174] に記載されている通り、全て大文字で現れる場合のみ、その意味で解釈されます。

3. Server-Timingヘッダーフィールド

Server-Timing ヘッダーフィールドは、与えられたリクエスト-レスポンスサイクルに対して、1つ以上の指標と説明を通知するために使用されます。RFC5234 に基づくABNF(拡張Backus-Naur形式)の 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 を参照し、#*OWStokenquoted-stringの定義を確認してください。

レスポンスには同じ metric-name を持つ server-timing-metric エントリが複数存在する場合があり、ユーザーエージェントはこれらすべてのエントリを処理し、公開しなければなりません(MUST)

ユーザーエージェントは、提供された指標をどの順序でも表示して構いません(MAY)。つまり、HTTPヘッダーフィールド内の指標の順序は重要ではありません。

このヘッダーフィールドは将来のパラメータ追加に対応できる拡張可能な構文で定義されています。レスポンスの Server-Timing ヘッダーフィールド内の特定の server-timing-param-name を認識しないユーザーエージェントは、そのトークンを無視し、エラーを通知せずに処理を継続しなければなりません(MUST)

あいまいさを避けるため、1つのserver-timing-metric内でserver-timing-param-nameは複数回現れるべきではありません(SHOULD NOT)。もし同じserver-timing-param-nameが複数回指定された場合、最初のインスタンスのみを考慮し、たとえserver-timing-paramが不完全または無効であっても、以降のすべての出現はエラー通知などをせずに無視しなければなりません(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)を定義します。いずれも任意です。

注記
  • HTTPオーバーヘッドを最小化するため、提供される名前や説明はできるだけ短く保つべきです。例:省略形を使用したり、任意値を可能な限り省略する。

  • クライアント・サーバー・中継機関間で時計同期が保証できないため、クライアントのタイムライン上で意味のあるstartTimeを割り当てることは不可能です。そのため、本仕様ではstartTime属性は意図的に省略されています。複数エントリ間の関係性を確立したい場合は、指標名や説明を使って独自データを通信することができます。

  • サーバーや関連する中継機関は、どの指標をいつユーザーエージェントに通知するかを完全に制御できます。例えば、プライバシーやセキュリティ上の理由で一部の指標へのアクセスが制限される場合があります。詳細は 6. プライバシーとセキュリティ セクションを参照してください。

Server-Timingヘッダーフィールドをパースするには、文字列fieldを与えて、以下の手順に従います:

  1. position位置変数として、最初はfieldの先頭を指す。

  2. nameを、コードポイントの並びを収集することで、fieldからU+003B(;)に等しくないものを、positionを基準に収集した結果とする。

  3. 先頭と末尾のASCII空白を除去するnameに適用する。

  4. nameが空文字列の場合、nullを返す。

  5. metricを新しいPerformanceServerTimingとして生成し、そのmetric namenameを設定する。

  6. paramsを空の順序付きマップとする。

  7. positionfieldの末尾でない間、以下を繰り返す:

    1. positionを1進める。

    2. paramNameを、コードポイントの並びを収集することでfieldからU+003D(=)に等しくないものを、positionを基準に収集した結果とする。

    3. 先頭と末尾のASCII空白を除去するparamNameに適用する。

    4. paramNameが空文字列であるか、params[paramName]が存在する場合、次へ

    5. positionを1進める。

    6. paramValueを空文字列とする。

    7. ASCII空白をスキップするfieldpositionで適用する。

    8. positionfieldのコードポイントがU+0022(")であれば:

      1. paramValueに、HTTP引用文字列を収集するの結果(extract-value flagをセットした状態)をfieldpositionで適用し、設定する。

      2. コードポイントの並びを収集するで、fieldからU+003B(;)に等しくないものをpositionを基準に収集する。結果は使用しない。

    9. それ以外の場合:

      1. rawParamValueを、コードポイントの並びを収集することでfieldからU+003B(;)に等しくないものをpositionを基準に収集した結果とする。

      2. paramValueを、rawParamValueの先頭と末尾のASCII空白を除去した結果とする。

  8. 設定するで、metricparamsparamsを設定する。

  9. metricを返す。

4. PerformanceServerTiming インターフェース

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 を実行する。

4.1 name 属性

name のgetter手順は、thismetric name を返すこと。

4.2 duration 属性

duration のgetter手順は以下の通り:

  1. thisparams["dur"] が 存在しない場合、0を返す。

  2. durthisparams["dur"] を 浮動小数点数値のパース規則でパースした結果とする。

  3. dur がエラーの場合は0を返す。そうでなければdurを返す。

注記

durationDOMHighResTimeStamp であり、通常はミリ秒単位の 継続時間 を表します。実際には強制できないため、duration は任意の時間単位を表すことができ、ミリ秒単位で 継続時間 を表すことが推奨されます。

4.3 description 属性

description のgetter手順は、thisparams["desc"] が 存在する場合はそれを返し、そうでなければ空文字列を返す。

PerformanceServerTiming は関連付けられた文字列 metric name を持ち、初期値は空文字列である。

PerformanceServerTiming は関連付けられた 順序付きマップ params を持ち、初期値は空である。

5. PerformanceResourceTiming インターフェースへの拡張

この仕様で部分的に拡張される PerformanceResourceTiming インターフェースは [RESOURCE-TIMING] で定義されています。

WebIDL[Exposed=(Window,Worker)]
partial interface PerformanceResourceTiming {
  readonly attribute FrozenArray<PerformanceServerTiming> serverTiming;
};

5.1 serverTiming 属性

serverTiming のgetter手順は以下の通り:

  1. entriesを新しいリストとする。

  2. fieldについて、thistiming infoserver-timing headers内:

    1. metricを、Server-Timingヘッダーフィールドをパースするfieldに適用した結果とする。

    2. metricがnullでなければ、appendmetricentriesに追加する。

  3. entriesを返す。

6. プライバシーとセキュリティ

このセクションは非規定(参考)です。

この仕様で定義されるインターフェースは、サーバータイミング指標を通知するリソースを含む任意のウェブページに対して、潜在的に機微なアプリケーションおよびインフラ情報を公開します。このため、PerformanceServerTimingインターフェースへのアクセスはデフォルトで同一オリジンポリシーによって制限されています。リソース提供者は、[RESOURCE-TIMING]にて定義されるTiming-Allow-Origin HTTPレスポンスヘッダーを追加し、サーバー指標へのアクセスを許可するドメインを明示的に指定できますが、ユーザーエージェントは 同一オリジン ポリシーの制限を維持してもよい(MAY)です。

Timing-Allow-Origin HTTPレスポンスヘッダーの利用に加え、サーバーはどの指標をいつ誰に返すかを制御するためのロジックも利用できます。例えば、サーバーは認証済みの正しいユーザーにのみ特定の指標を提供し、それ以外のユーザーには何も提供しない場合があります。

7. IANAに関する考慮事項

永続メッセージヘッダーフィールド登録簿は、以下の登録内容で更新されるべきです([RFC3864]参照):

7.1 Server-Timingヘッダーフィールド

ヘッダーフィールド名
Server-Timing
適用プロトコル
http
ステータス
標準
著者/変更管理者
W3C
仕様書
この仕様(Server-Timingヘッダーフィールド参照)

A.

このセクションは非規定(参考)です。

> 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

上記のヘッダーフィールドは、サーバーがユーザーエージェントにデータを通知するためのあらゆる方法を示す6つの異なる指標を伝えています:指標名のみ、値付き指標、値・説明付き指標、説明付き指標など。例えば、上記の指標はexample.com/resource.jpgの取得について次のように示すかもしれません。

  1. キャッシュミスが発生した。
  2. リクエストは「atl」データセンター("dc")を経由した。
  3. データベース("db")の時間は53msだった。
  4. キャッシュの読み取りは23.2msかかった。
  5. アプリケーションサーバー("app")は"customView"テンプレートや関数の処理に47.2msかかった。
  6. サーバー上でのリクエスト-レスポンスサイクルの総時間は123.4msであり、これはレスポンス末尾に記録され、トレーラーフィールド経由で通知された。

アプリケーションは、提供されたJavaScriptインターフェースを使って、これらの指標を収集・処理・活用できます:

// serverTiming entriesは'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('遅い server-timing エントリ =',
          JSON.stringify({url, entryType, name, duration, description}, null, 2))
      }
    }
  }
}

B. ユースケース

このセクションは非規定(参考)です。

B.1 開発者ツールにおけるサーバータイミング

サーバー処理時間はリクエスト全体の時間の大きな割合を占めることがあります。例えば、動的レスポンスは複数のデータベースクエリやキャッシュ参照、API呼び出し、関連データの処理とレンダリングなどを必要とする場合があります。同様に、静的レスポンスでもサーバーの過負荷やキャッシュの遅延などで遅延することがあります。

現在、ユーザーエージェントの開発者ツールではリクエストの開始時刻やレスポンスの最初と最後のバイトの受信時刻は表示できますが、サーバー上でどこやどのように時間が使われたかは見えません。つまり、開発者はサーバーにパフォーマンスのボトルネックがあるかどうか、その場合どのコンポーネントかを迅速に診断できません。現状、この問いに答えるには、開発者はサーバーログを確認したり、レスポンス内にパフォーマンスデータを埋め込んだり、外部ツールを使ったりしなければなりません。これではボトルネックの特定や診断が困難、場合によっては非現実的です。

Server Timingは、サーバーが関連するパフォーマンス指標をクライアントに通知し、クライアント側で開発者ツールに直接表示できる標準的な仕組みを定義します。例えば、リクエストにサーバー送信の指標を付与し、レスポンス生成時のどこ/どう時間が使われたかを可視化できます。

B.2 自動分析のためのサーバータイミング

開発者ツールでサーバー送信のパフォーマンス指標を表示するだけでなく、標準のJavaScriptインターフェースによって、分析ツールがこれらの指標を自動的に収集・処理・ビーコン送信・集計し、運用分析やパフォーマンス分析に活用できます。

B.3 リクエストルーティングパフォーマンスの測定

Server Timingにより、オリジンサーバーはリクエスト処理中のどこやどのように時間が使われているかのパフォーマンス指標を通知できます。しかし、同じリクエストとレスポンスが複数のプロキシ(例:キャッシュサーバー、ロードバランサー等)を経由する場合もあり、それぞれが独自の遅延や指標を加えたい場合があります。

例えば、CDNエッジノードは、どのデータセンターが使われたか、リソースがキャッシュにあったか、キャッシュやオリジンサーバーからレスポンス取得にどれだけ時間がかかったかなどを報告できます。また、他のプロキシでも同様の処理が繰り返され、リクエストがどのようにルーティングされ、どこで時間を使ったかの全体像が把握できます。

同様に、Service Workerが有効な場合、一部またはすべてのナビゲーションやリソースリクエストがService Worker経由でルーティングされます。実質的にService Workerはローカルプロキシとして、リクエストの再ルーティングやキャッシュレスポンスの提供、レスポンスの生成などを行えます。その結果、Server TimingはService Workerがリクエスト処理の方法(サーバー取得かローカルキャッシュか、各処理ステップの継続時間など)についてカスタム指標を報告できるようにします。

C. 謝辞

このセクションは非規定(参考)です。

本書は、[NAVIGATION-TIMING]、[RESOURCE-TIMING]、[PERFORMANCE-TIMELINE-2]、[RFC6797]仕様のライセンスにより許可された部分を再利用しています。

D. 参考文献

D.1 規定参照

[fetch]
Fetch Standard. Anne van Kesteren. WHATWG. 現行標準. URL: https://fetch.spec.whatwg.org/
[hr-time]
High Resolution Time. Yoav Weiss. W3C. 2023年3月22日. W3C作業草案. URL: https://www.w3.org/TR/hr-time-3/
[html]
HTML標準. Anne van Kesteren; Domenic Denicola; Ian Hickson; Philip Jägenstedt; Simon Pieters. WHATWG. 現行標準. URL: https://html.spec.whatwg.org/multipage/
[infra]
Infra Standard. Anne van Kesteren; Domenic Denicola. WHATWG. 現行標準. URL: https://infra.spec.whatwg.org/
[RESOURCE-TIMING]
Resource Timing. Yoav Weiss; Noam Rosenthal. W3C. 2022年10月4日. W3C勧告候補. URL: https://www.w3.org/TR/resource-timing-2/
[RFC2119]
Key words for use in RFCs to Indicate Requirement Levels. S. Bradner. IETF. 1997年3月. 現行のベストプラクティス. URL: https://www.rfc-editor.org/rfc/rfc2119
[RFC3864]
Registration Procedures for Message Header Fields. G. Klyne; M. Nottingham; J. Mogul. IETF. 2004年9月. 現行のベストプラクティス. URL: https://www.rfc-editor.org/rfc/rfc3864
[RFC5234]
Augmented BNF for Syntax Specifications: ABNF. D. Crocker, Ed.; P. Overell. IETF. 2008年1月. インターネット標準. URL: https://www.rfc-editor.org/rfc/rfc5234
[RFC7230]
Hypertext Transfer Protocol (HTTP/1.1): Message Syntax and Routing. R. Fielding, Ed.; J. Reschke, Ed.. IETF. 2014年6月. 提案標準. URL: https://httpwg.org/specs/rfc7230.html
[RFC8174]
Ambiguity of Uppercase vs Lowercase in RFC 2119 Key Words. B. Leiba. IETF. 2017年5月. 現行のベストプラクティス. URL: https://www.rfc-editor.org/rfc/rfc8174
[WEBIDL]
Web IDL標準. Edgar Chen; Timothy Gu. WHATWG. 現行標準. URL: https://webidl.spec.whatwg.org/

D.2 参考参照

[NAVIGATION-TIMING]
Navigation Timing. Zhiheng Wang. W3C. 2012年12月17日. W3C勧告. URL: https://www.w3.org/TR/navigation-timing/
[PERFORMANCE-TIMELINE-2]
Performance Timeline. Nicolas Pena Moreno. W3C. 2022年11月15日. W3C勧告候補. URL: https://www.w3.org/TR/performance-timeline/
[RFC6797]
HTTP Strict Transport Security (HSTS). J. Hodges; C. Jackson; A. Barth. IETF. 2012年11月. 提案標準. URL: https://www.rfc-editor.org/rfc/rfc6797