- From: James Simonsen <simonjam@chromium.org>
- Date: Wed, 27 Apr 2011 11:29:26 -0700
- To: public-web-perf <public-web-perf@w3.org>
- Message-ID: <BANLkTinAF+o9XigG14=uo2Hz-W0dHhKPCw@mail.gmail.com>
In light of last week's discussion, Tony and I have come up with simplified versions of the Resource Timing and User Timing APIs. Please take a look and let us know what you think. Thanks, James Resource TimingIDLinterface PerformanceResourceTiming { readonly attribute DOMString url; readonly attribute unsigned long long redirectStart; readonly attribute unsigned long long redirectEnd; readonly attribute unsigned long long fetchStart; readonly attribute unsigned long long domainLookupStart; readonly attribute unsigned long long domainLookupEnd; readonly attribute unsigned long long connectStart; readonly attribute unsigned long long connectEnd; readonly attribute unsigned long long secureConnectionStart; readonly attribute unsigned long long requestStart; readonly attribute unsigned long long responseStart; readonly attribute unsigned long long responseEnd; readonly attribute unsigned long long fetchEnd; }; [Supplemental] interface PerformanceTiming { ResourceTiming[] getResourceTimings (in optional Location location); void enableResourceTimings(); void disableResourceTimings(); void clearResourceTimings(); }; DescriptiongetResourceTimings()Returns a snapshot of the currently collected resource information in the event log. If a location is specified, only entries with a matching location are returned. The log must have capacity for at least 1000 resources. After that, the UA may choose to ignore new resources. enableResourceTimings()Enable resource timing collection. When enabled, the event log will record the timings for any new resources that are loaded. By default, resource timings are disabled. disableResourceTimings()Disables resource timings. New entries are no longer collected in the event log. clearResourceTimings()Clears the event log of all resources. ExamplesGet Everythingperformance.timing.getResourceTimings() -> [{url: “http://resource1”, redirectStart: 1, … }, {url: “http://resource2”, redirectStart: 2, … }, {url: “http://resource2”, redirectStart: 3, … }, …] Get One Resourceperformance.timing.getResourceTimings(“http://resource1”) -> [{url: “http://resource1”, redirectStart: 1, … }] One Resource Requested Multiple Timesperformance.timing.getResourceTimings(“ http://resource2”) -> [{url: “http://resource2”, redirectStart: 2, … }, {url: “http://resource2”, redirectStart: 3, … }] Get a Specific Resource <script src=”http://resource1” id=”myElement”></script> ... performance.timing.getResourceTimings(document.getElementById(‘myElement’).src) -> [{url: “http://resource1”, redirectStart: 1, … }] User TimingIDLinterface UserMark { readonly attribute DOMString name; readonly attribute unsigned long long value; }; [Supplemental] interface PerformanceTiming { const string MARK_FULLY_LOADED = "fullyLoaded"; const string MARK_FULLY_VISIBLE = "fullyVisible"; const string MARK_ABOVE_THE_FOLD = "aboveTheFold"; const string MARK_TIME_TO_USER_ACTION = "timeToUserAction"; void mark(in DOMString markName); UserMark[] getMarks(in optional DOMString markName); void clearMarks(); }; Descriptionmark()Creates a new entry in the event log with the given name. The value is the current time according to the monotonic clock. The event log must be large enough to record at least 1000 marks. After 1000 marks, the UA may choose to ignore subsequent calls to mark(). getMarks()Returns a snapshot of the currently known marks. If a mark name is specified, only entries matching that mark name are returned. clearMarks()Clear the event log of all marks. ExamplesMultiple Marksperformance.timing.mark(“start”); performance.timing.mark(“end”); performance.timing.getMarks(); -> [{name: “start”, value: 1}, {name: “end”, value: 2}] performance.timing.getMarks(“start”); -> [{name: “start, value: 1}] Repeated Marksperformance.timing.mark(“step”); performance.timing.mark(“step”); performance.timing.getMarks(“step”); -> [{name: “step”, value: 1}, {name: “step”, value: 2}] Rationale for significant changes 1. Resource Timings no longer have a “type” and “id”. The id and type attributes make sense for many types of resources which have associated DOM elements. But a strong associations between DOM elements and the requests performed isn’t always the case. This leads to surprising behavior for both the data members and their associated getter methods: 1. id doesn’t mean anything for a CSS or plugin subresource. 2. id is a snapshot at the time the request was made. It may change during or after the request. 3. id may not be unique and an element may initiate multiple requests. 4. The initiator may be indeterminate and thus the id or type could be misleading. The getter methods are largely redundant with document’s getElementById and getElementsByTagName and are missing the functionality of getElementsByClassName and getElementsByName. Encouraging users to use existing DOM querying methods to find URLs to look up in the map enables the same usage patterns, but is ultimately more flexible/future-proof and keeps the interface simpler. 1. Resource Timing is now explicitly enabled. Browsers take great care to use memory efficiently. While it was measured that the interface will consume 10s of K for typical sites<http://lists.w3.org/Archives/Public/public-web-perf/2010Dec/0024.html>, all calculations were based on 200 resources or less. In reality, long running apps (and even traditional pages that rotate ads or periodically beacon) will eventually max out the structure (currently 1,000 entry limit). 1,000 x 124 bytes is now 124k... and that’s just one tab. This still may not seem like a terrible amount of memory, but couple that with the fact that very few pages will actually be using this data. Even sites that do use the interface will probably only do so to sample performance on a small subset of requests (due to the large upload size of the JSON -- ~350bytes/entry without URLs). Popular browser developer tools require the user to explicitly enable recording of network resources, following that precedent we are requiring timing of resources to be explicitly enabled. As an aside, the explicit start/stop also removes the need for the complexity of buffer size management (onbufferfull and setResourceTimingBufferSize()). 2. User Timing no longer has measures. The value of User Timing is to provide a monotonically increasing, high precision timer which would otherwise be unavailable; as well as to provide a standard location for developer tools and extensions to find application specific timings. Measures are syntactical sugar that a JS library could trivially layer on if developer wants to think about times in terms of measures. Measures were omitted from the Navigation Timing and Resource Timing APIs because they do not provide additional data and complicate the interface. To be consistent, they have been omitted from User Timing as well. It is worth noting that any of these features could be added back in should there be sufficient demand. Simplifying the API will allow us to standardize on the core faster and expand if necessary.
Received on Wednesday, 27 April 2011 18:31:58 UTC