Re: [UserTiming] Feedback on latest draft

   You folks are awesome! Please find comments inline.

On Mon, Jan 31, 2011 at 9:02 PM, Tony Gentilcore <tonyg@google.com> wrote:

> Excellent summary. I'd like to consider a much simpler interface.
> Justifications inline below.
>
>   [Supplemental]
>   interface PerformanceTiming {
>     // Returns Object with string keys and array of numbers values.
>     readonly attribute Object marks;
>   };
>

>   [Supplemental]
>   interface Performance {
>     // TBD: Standardize a set of universally applicable mark names
> appropriate for passing to mark().
>     const string MARK_FULLY_VISIBLE = "fullyVisible";
>     const string MARK_FULLY_INTERACTIVE = "fullyInteractive";
>
>     void mark(in DOMString name);
>     void clearMarks();
>   };
>
>
    This looks good. We might want to explicitly define the mark object into
an interface.




> On Thu, Jan 27, 2011 at 4:58 PM, Anderson Quach <aquach@microsoft.com>wrote:
>
>> *User Timing*
>>
>>
>>
>> The IE-9 Beta has a running implementation of the first draft [1]
>> available here [2].
>>
>>
>>
>> Requirements discussed
>>
>> ·         R1: High precision marks accessible by mark name, within 1ms
>> accuracy
>>
>> ·         R2: Ease of store and access of marks
>>
>> ·         R3: Does not burden the browser, efficient use of CPU and
>> Memory
>>
>>
>>
>> Use cases discussed
>>
>> ·         UC1: A web developer makes unique marks in their web-page /
>> web-app.
>>
>> ·         UC2: A web developer uses marks in repeated or iterative
>> patterns. For example, a web developer may want to measure successive clicks
>> denoted by a single name called “my_action”.
>>
>> ·         UC3: Analytics companies report on standardized markers
>>
>> ·         UC4: Developer tools consume user marks interface
>>
>>
>>
>> Nice to have, as discussed
>>
>> ·         NH1: Measures – achievable through JavaScript, we can create a
>> best practice library that leverages the implementation of mark to create
>> measures, which is a delta between marks and/or a date time.
>>
>>
>>
>> With the latest User Timing spec [3] we have the following concerns.
>>
>>
>>
>> *Issue 1 – Does not meet UC2.*
>>
>> The ‘.user’ attribute currently does not support the ability to retrieve a
>> list of marks to meet Use Case 2 (UC2).  The getMarks() API solves this by
>> returning an array of all marks that match that name.  The web-developer can
>> get the latest single mark using getMark().
>>
>
> Multiple marks under the same name seems like an important requirement.
> However, I think that is orthogonal to whether we choose an attribute or
> method to expose it. For instance, .marks could expose an object with string
> keys and array of numbers values.
>
> console.log(performance.timing.marks)
> >> {
>   fullyLoaded: [123456789],
>   widgetClicked: [123456790, 1234567891]
> }
>
> It would be easy to understand as developers already know how to work with
> objects and we wouldn't have to implement custom getters. For instance:
>
> console.log(performance.timing.marks.fullyLoaded)
> >> [123456789]
> console.log(performance.timing.marks["widgetClicked"])
> >> [123456790, 1234567891]
>
> Also, since it is already JSON, it is trivial to ping home and more compact
> than the getMarks() proposal. Compare the size difference:
>
> console.log(performance.getMarks())
> >> [{name: "fullyLoaded", time: 123456789}, {name: "widgetClicked",
> time: 123456790}, {name: "widgetClicked", time: 1234567891}]
>
> console.log(performance.timing.marks)
> >>{fullyLoaded: [123456789], widgetClicked: [123456790, 1234567891]}
>
>
>>
>> *Issue 2 – Ease of use, possible confusion*
>>
>> *Assuming we support the ability to retrieve multiple marks from the same
>> name.
>>
>>
>>
>> If we change from the getMark()/getMarks() API to a '.user' attribute,
>> we're overloading that attribute getter for multiple use cases: filtering
>> and indexing.  This might lead to confusion.
>>
>>
>> For example:
>>
>> Use Cases
>>
>> getMark()/getMarks()
>>
>> .userTiming attribute
>>
>> *usage*
>>
>> *returns*
>>
>> *usage*
>>
>> *returns*
>>
>> Get all marks
>>
>> performance.getMarks()
>>
>> array
>>
>> performance.user
>>
>> array
>>
>> Get the first mark
>>
>> performance.getMarks()[0]
>>
>> mark
>>
>> performance.user[0]
>>
>> mark
>>
>> Get all marks named "foo"
>>
>> performance.getMarks("foo")
>>
>> array
>>
>> performance.user["foo"]
>>
>> array
>>
>> Get the first "foo" mark
>>
>> performance.getMarks("foo")[0]
>>
>> mark
>>
>> performance.user["foo"][0]
>>
>> mark
>>
>> Get all marks named "0"
>>
>> performance.getMarks("0")
>>
>> array
>>
>> performance.user["0"]
>>
>> array
>>
>> Get the latest "foo" mark
>>
>> performance.getMark("foo")
>>
>> mark
>>
>> performance.user["foo"][ performance.user["foo"].length-1]
>>
>> mark
>>
>>
>>
>> There can be confusion may come from the fact that if .user is indexed by
>> a number, it is a single mark (the nth mark).  But if it's indexed by a
>> string, it's an array of marks that match that name.
>>
>>
>>
>> The getMark()/getMarks() API [1], on the other hand, separates the
>> filtering, based on the API parameters, from indexing which web developers
>> can access in a standard JavaScript array returned from the API.  getMarks()
>> always returns an array, which can be iterated over the standard way.  The
>> getMark() interface returns the latest mark for that name and is slightly
>> easier than the .user way (performance.userTiming["foo"][
>> performance.userTiming["foo"].length-1]);
>>
>
> There's no table of examples to consider w/ the Object marks attribute.
>
>
>>
>>
>> *Issue 3 – Efficiency of data structures, Requirement 3 (R3)*
>>
>> In terms of design efficiency data structure of having a "PerformanceMark"
>> does not necessarily require that it can also be a measure.  If it's just a
>> mark, it carries additional 'type' and 'measure' attributes that are not
>> appropriate.  If we do add measures, we should consider splitting them into
>> another object type.
>>
>
> I think we should drop measures for the same reasons we dropped them in
> navigation timing.
>

   yup, if we drop the measures, the data type can be much simplified.

cheers,
Zhiheng


>
>
>>
>>
>> *Issue 4 – Naming*
>>
>> The attribute name ‘user’ is ambiguous.
>>
>
> Agreed. If we keep it as an attribute it should be named "marks." If it is
> a method it should be "getMarks()".
>
>
>>
>>
>> [1]
>> http://dvcs.w3.org/hg/webperf/raw-file/d1498d8e0e5e/specs/UserTiming/Overview.html<https://dvcs.w3.org/hg/webperf/raw-file/d1498d8e0e5e/specs/UserTiming/Overview.html>
>>
>> [2] http://ie.microsoft.com/testdrive/info/downloads/Default.html
>>
>> [3]
>> http://dvcs.w3.org/hg/webperf/raw-file/tip/specs/UserTiming/Overview.html
>>
>>
>>
>> Best Regards,
>>
>> Anderson, Nic and Karen
>>
>> Internet Explorer
>>
>
>

Received on Wednesday, 2 February 2011 00:42:33 UTC