Copyright © 2016 W3C® (MIT, ERCIM, Keio, Beihang). W3C liability, trademark and document use rules apply.
This specification extends the High Resolution Time specification [HR-TIME-2] by providing methods to store and retrieve high resolution performance metric data.
This section describes the status of this document at the time of its publication. Other documents may supersede this document. A list of current W3C publications and the latest revision of this technical report can be found in the W3C technical reports index at http://www.w3.org/TR/.
This new version is aligned with [HR-TIME-2] and introduces filtering
and
performance
observers
.
This is a work in progress and may change without any notices.
This document was published by the Web Performance Working Group as a Working Draft.
This document is intended to become a W3C Recommendation.
If you wish to make comments regarding this document, please send them to
public-web-perf@w3.org
(subscribe,
archives)
with [Performance Timeline]
at the start of your email's subject.
All comments are welcome.
Publication as a Working Draft does not imply endorsement by the W3C Membership. This is a draft document and may be updated, replaced or obsoleted by other documents at any time. It is inappropriate to cite this document as other than work in progress.
This document was produced by a group operating under the 5 February 2004 W3C Patent Policy. W3C maintains a public list of any patent disclosures made in connection with the deliverables of the group; that page also includes instructions for disclosing a patent. An individual who has actual knowledge of a patent which the individual believes contains Essential Claim(s) must disclose the information in accordance with section 6 of the W3C Patent Policy.
This document is governed by the 1 September 2015 W3C Process Document.
This section is non-normative.
Accurately measuring performance characteristics of web applications is an important aspect of making web applications faster. This specification defines the necessary Performance Timeline primitives that enable web developers to access, instrument, and retrieve various performance metrics from the full lifecycle of a web application.
[NAVIGATION-TIMING-2], [RESOURCE-TIMING], and [USER-TIMING] are examples of specifications that define timing information related to the navigation of the document, resources on the page, and developer scripts, respectively. Together these and other performance interfaces define performance metrics that describe the Performance Timeline of a web application. For example, the following script shows how a developer can access the Performance Timeline to obtain performance metrics related to the navigation of the document, resources on the page, and developer scripts:
<!doctype html> <html> <head> </head> <body onload="init()"> <img id="image0" src="https://www.w3.org/Icons/w3c_main.png" /> <script> function init() { performance.mark("startWork"); // see [USER-TIMING] doWork(); // Some developer code performance.mark("endWork"); measurePerf(); } function measurePerf() { var perfEntries = performance.getEntries(); for (var i = 0; i < perfEntries.length; i++) { if (window.console) { console.log("Name: " + perfEntries[i].name + " Entry Type: " + perfEntries[i].entryType + " Start Time: " + perfEntries[i].startTime + " Duration: " + perfEntries[i].duration + "\n"); } } } </script> </body> </html>
Alternatively, the developer can observe the Performance Timeline
and be notified of new performance metrics via the
PerformanceObserver
interface:
<!doctype html> <html> <head> </head> <body> <img id="image0" src="https://www.w3.org/Icons/w3c_main.png" /> <script> var doneObservingEvents = false; var observer = new PerformanceObserver(function(list) { var perfEntries = list.getEntries(); for (var i = 0; i < perfEntries.length; i++) { if (window.console) { console.log("Name: " + perfEntries[i].name + " Entry Type: " + perfEntries[i].entryType + " Start Time: " + perfEntries[i].startTime + " Duration: " + perfEntries[i].duration + "\n"); } } // maybe disconnect after processing the events. if (doneObservingEvents) { observer.disconnect(); } }); // subscribe to Frame-Timing and User-Timing events observer.observe({entryTypes: ['frame', 'mark', 'measure']}); </script> </body> </html>
The PerformanceObserver
interface was added in Performance
Timeline Level 2 and is designed to address limitations of the buffer-based
approach shown in the first example. By using the PerformanceObserver
interface, the application can:
The developer is encouraged to use PerformanceObserver
where
possible. Further, new performance API's and metrics may only be available
through the PerformanceObserver
interface.
As well as sections marked as non-normative, all authoring guidelines, diagrams, examples, and notes in this specification are non-normative. Everything else in this specification is normative.
The key words MUST and MUST NOT are to be interpreted as described in [RFC2119].
Conformance requirements phrased as algorithms or specific steps may be implemented in any manner, so long as the end result is equivalent. (In particular, the algorithms defined in this specification are intended to be easy to follow, and not intended to be performant.)
The IDL fragments in this specification must be interpreted as required for conforming IDL fragments, as described in the Web IDL specification. [WebIDL]
Each ECMAScript global environment has:
PerformanceEntry
objects. It is initially empty.To queue a PerformanceEntry (new entry), run these steps:
PerformanceObserver
objects.
PerformanceObserverInit
entryTypes
includes
new entry’s entryType
value, append
observer to interested observers.
PerformanceObserver
object po in notify
list, run these steps:
The performance timeline task queue is a low priority queue that, if possible, should be processed by the user agent during idle periods to minimize impact of performance monitoring code.
PerformanceEntry
interfaceThe PerformanceEntry
interface hosts the performance data of
various metrics.
[Exposed=(Window,Worker)]
interface PerformanceEntry
{
readonly attribute DOMString name
;
readonly attribute DOMString entryType
;
readonly attribute DOMHighResTimeStamp startTime
;
readonly attribute DOMHighResTimeStamp duration
;
serializer = {attribute};
};
The name
attribute MUST return an
identifier for this PerformanceEntry
object. This identifier does
not have to be unique.
The entryType
attribute MUST return
the type of the interface represented by this
PerformanceEntry
object.
Valid entryType values are: "mark
[USER-TIMING],
"measure"
[USER-TIMING], "navigation"
[NAVIGATION-TIMING-2],
"frame"
[FRAME-TIMING], "resource"
[RESOURCE-TIMING],
"server"
[SERVER-TIMING].
The startTime
attribute MUST return
the time value of the first recorded timestamp of this
performance metric.
The duration
attribute MUST return the
time value of the duration of the entire event
being recorded by this PerformanceEntry
. Typically, this would
be the time difference between the last recorded timestamp and the
first recorded timestamp of this PerformanceEntry
. If the
duration concept doesn't apply, a performance metric may choose to
return a duration
of 0
.
Performance
interfaceThis extends the Performance interface [HR-TIME-2] and hosts performance related attributes and methods used to retrieve the performance metric data from the Performance Timeline.
dictionary PerformanceEntryFilterOptions {
DOMString name
;
DOMString entryType
;
DOMString initiatorType
;
};
The name
dictionary
member filters the name
of
PerformanceEntry
object.
The entryType
dictionary
member filters the entryType
of
PerformanceEntry
object.
The initiatorType
dictionary member filters the initiatorType
of
PerformanceResourceTiming
object.
partial interfacePerformance
{PerformanceEntryList
getEntries
(optionalPerformanceEntryFilterOptions
filter);PerformanceEntryList
getEntriesByType
(DOMString type);PerformanceEntryList
getEntriesByName
(DOMString name, optional DOMString type); }; typedef sequence<PerformanceEntry
> PerformanceEntryList;
The getEntries
method returns a PerformanceEntryList
object that
contains a list of PerformanceEntry
objects, sorted in
chronological order with respect to startTime
, that match the
following criteria:
PerformanceEntryList
.
filter
that is present and the second element is
the value of that dictionary member.
PerformanceEntry
object
(entryObject) in the performance entry buffer, in
chronological order with respect to startTime
:
The getEntriesByType
method
returns a PerformanceEntryList
object returned by
getEntries({'entryType': type})
.
The getEntriesByName
method
returns a PerformanceEntryList
object returned by
getEntries({'name': name})
if optional entryType
is omitted, and
getEntries({'name': name, 'entryType': type})
otherwise.
PerformanceObserver
interfaceThe PerformanceObserver
interface can be used to observe the
Performance Timeline and be notified of new performance entries as
they are recorded.
Each PerformanceObserver
has these associated concepts:
PerformanceEntry
objects called the observer
buffer that is initially empty.
The PerformanceObserver(callback)
constructor must create a new
PerformanceObserver
object with callback set to
callback and then return it.
A registered performance observer consists of an observer
(a PerformanceObserver
object) and options (a
PerformanceObserverInit
dictionary).
dictionary PerformanceObserverInit { required sequence<DOMString>entryTypes
; }; [Exposed=(Window,Worker)] interface PerformanceObserverEntryList {PerformanceEntryList
getEntries(optionalPerformanceEntryFilterOptions
filter);PerformanceEntryList
getEntriesByType(DOMString type);PerformanceEntryList
getEntriesByName(DOMString name, optional DOMString type); }; callback PerformanceObserverCallback = void (PerformanceObserverEntryList
entries,PerformanceObserver
observer); [Constructor(PerformanceObserverCallback
callback), Exposed=(Window,Worker)] interfacePerformanceObserver
{ voidobserve
(PerformanceObserverInit
options); voiddisconnect
(); };
PerformanceObserverInit.entryTypes
is a list of valid entryType
names to be
observed. The list MUST NOT be empty and types not recognized by
the user agent MUST be ignored.
To keep the performance overhead to minimum the application should only subscribe to event types that it is interested in, and disconnect the observer once it no longer needs to observe the performance data. Filtering by name is not supported, as it would implicitly require a subscription for all event types — this is possible, but discouraged, as it will generate a significant volume of events.
The PerformanceObserverEntryList
interface provides the same
getEntries
, getEntriesByType
,
getEntriesByName
methods as the
Performance
interface, except that
PerformanceObserverEntryList
operates on the observed emitted
list of events instead of the global timeline.
The observe
method instructs the
user agent to register the observer and must run these
steps:
entryTypes
attribute is not present, throw a JavaScript
TypeError
.
entryType
entryType names within the entryTypes
sequence, and replace
the entryTypes
sequence with the new filtered sequence.
entryTypes
attribute is an empty sequence,
throw a
JavaScript TypeError
.
options
with options.
observer
and options as the options
.
The disconnect
method must
remove the context object from the list of
PerformanceObserver
objects associated with the ECMAScript
global environment of the interface object, and also
empty context object's observer buffer.