This specifications defines an interface to help web developers measure the performance of their applications by giving them access to high precision timestamps and enable them to do comparisons between them.
- Read the latest draft: https://w3c.github.io/user-timing/
- Discuss on public-webperf
See also Web performance README
User Timing enables developers to create a PerformanceMark
, which contains a
provided string in name
, with a high resolution timestamp (see
hr-time in its startTime
, and optionally
some additional metadata in its detail
.
A developer can create such an object via performance.mark()
and can query
existing entries via performance.getEntriesByType('mark')
(or other getters;
see performance-timeline or via
the PerformanceObserver
.
The following examples illustrate usage of performance.mark()
with various
parameters:
performance.mark('mark1')
: Creates aPerformanceMark
whose name is 'mark1' and whosestartTime
is the current high resolution time.performance.mark('mark2', {startTime: 5.4, detail: det})
: Creates aPerformanceMark
whose name is 'mark2', whosestartTime
is 5.4, and whosedetail
is the objectdet
.
Every time performance.mark()
is invoked, a new PerformanceMark
entry needs
to be stored by the browser so that it can be later queried by the developer.
The performance.clearMarks()
method enables developers to clear some of the
memory used by such calls. In particular:
performance.clearMarks()
: Clears all marks from theWindow
orWorker
from which the method is invoked.performance.clearMarks('mark1')
: Clears all marks fromWindow
orWorker
from which the method is invoked, whose name is 'mark1'.
User Timing also enables developers to create a PerformanceMeasure
, which is an
object that represents some time measurement between two points in time, and each
point in time may be represented by a PerformanceMark
. A PerformanceMeasure
has an associated name
, a high resolution timestamps corresponding to the initial
point in time in startTime
, the delta between the end-time and the startTime
in
duration
, and optionally some additional metadata in its detail
.
A developer can create a PerformanceMeasure
entry via performance.measure()
and
it may query existing entries via performance.getEntriesByType('measure')
or via
PerformanceObserver
(i.e. in the same way as for PerformanceMark
).
The following examples illustrate usage of performance.measure()
with various
parameters:
performance.measure('measure1')
: Creates aPerformanceMeasure
whosename
is 'measure1', whosestartTime
is 0, and whoseduration
is the current high resolution time.performance.measure('measure2', 'requestStart')
: Creates aPerformanceMeasure
whose name is 'measure2', whosestartTime
is equal toperformance.timing.requestStart - performance.timing.navigationStart
(see the PerformanceTiming interface for all the strings that are treated as special values inpeformance.measure()
calls), and whose end-time is the current high resolution timestamp ---duration
will be the delta between the end-time andstartTime
.performance.measure('measure2', 'myMark')
: Creates aPerformanceMeasure
where name is 'measure2', wherestartTime
is the timestamp from thePerformanceMark
whosename
is'myMark'
, and where end-time is the current high resolution timestamp. If there are no marks with such aname
, an error is thrown. If there are multiple marks with such aname
, the latest one is used.performance.measure('measure3', 'startMark', 'endMark')
: Creates aPerformanceMeasure
whosename
is 'measure3', whosestartTime
is thestartTime
of the latestPerformanceMark
withname
'startMark', and whose end-time is thestartTime
of the latestPerformanceMark
withname
'endMark'.performance.measure('measure4', 'startMark', 'domInteractive')
: Creates aPerformanceMeasure
whosename
is 'measure4',startTime
is as in the above example, and end-time isperformance.timing.domInteractive - performance.timing.navigationStart
.performance.measure('measure5', {start: 6.0, detail: det})
: Creates aPerformanceMeasure
whosename
is 'measure5',startTime
is 6.0, end-time is the current high resolution timestamp, anddetail
is the objectdet
.performance.measure('measure6', {start: 'mark1', end: 'mark2'})
: Creates aPerformanceMeasure
whosename
is 'measure6',startTime
is thestartTime
of thePerformanceMark
withname
equal to 'mark1', and end-time is thestartTime
of thePerformanceMark
withname
equal to 'mark2'.performance.measure('measure7', {end: 10.5, duration: 'mark1')
: Creates aPerformanceMeasure
wherename
is 'measure7',duration
is thestartTime
of thePerformanceMark
withname
equal to 'mark1', andstartTime
is equal to10.5 - duration
(since end-time is 10.5).performance.measure('measure8', {start: 20.2, duration: 2, detail: det}
: Creates aPerformanceMeasure
withname
set to 'measure8',startTime
set to 20.2,duration
set to 2, anddetail
set to the objectdet
.
The following examples would throw errors and hence illustrate incorrect usage of
peformance.measure
:
performance.measure('m', {start: 'mark1'}, 'mark2')
: If the second parameter is a dictionary, then the third parameter must not be provided.performance.measure('m', {duration: 2.0})
: In the dictionary, one ofstart
orend
must be provided.performance.measure('m', {start: 1, end: 4, duration: 3})
: In the dictionary, not all ofstart
,end
, andduration
should be provided.
This is the analogue to performance.clearMarks()
for PerformanceMeasure
cleanup:
performance.clearMeasures()
clears allPerformanceMeasure
objects.performance.clearMeasures('measure1')
clearsPerformanceMeasure
objects whosename
is 'measure1'.
A developer can obtain a high resolution timestamp directly via performance.now()
, as
defined in hr-time. However, User Timing enables
tracking timestamps that may happen in very different parts of the page by enabling the
developer to use names to identify these timestamps. Using User Timing instead of variables
containing performance.now()
enables the data to be surfaced automatically by analytics
providers that have User Timing support as well as in the developer tooling of browsers that
support exposing these timings. This kind of automatic surfacing is not possible directly via
HR-Time.
For instance, the following could be used to track the time it takes for a user from the time a cart is created to the time that the user completes their order, assuming a Single-Page-App architecture:
// Called when the user first clicks the "Add to cart" button.
function onBeginCart() {
const initialDetail = // Compute some initial metadata about the user.
performance.mark('beginCart');
}
// Called after the user clicks on "Complete transaction" button in checkout.
function onCompleteTransaction() {
const finalDetail = // Compute some final metadata about the user and the transaction.
performance.measure('transaction', {start: 'beginCart', detail: finalDetail});
}
While developers could calculate those time measurements using performance.now()
, using User
Timing enables both better ergonomics and standardized collection of the results. The latter
enables Analytics providers and developer tools to collect and report site-specific measurements,
without requiring any knowledge of the site or its conventions.