[UserTiming] Unifying marks and measures

As discussed on last week's call, here's one way to tie marks and measures
into the same concept while still preserving the functionality of both. It
largely boils down to semantics.

*Overview*

void mark(in DOMString name);
unsigned long long markEnd(in DOMString name);
Object getMarks(in optional DOMString name);
void clearMarks(in optional DOMString name);

*Examples to illustrate behavior*

1. Measure something:

mark("sleep3");
sleep(3);
markEnd("sleep3");
> 3
getMarks()
> { "sleep3": [ { "t": 1305712151745, "dur": 3 } ] }

2. Clear everything:

clearMarks()
getMarks()
> { }

3. Create a new mark:

mark(performance.MARK_FULLY_LOADED)
getMarks()
> { "fullyLoaded": [ { "t": 1305712151745 } ] }

4. Improper usage (no start):

clearMarks()
markEnd("doesNotExist")
> 0
getMarks()
> { }

5. Improper usage (end twice):

mark("doubleEnd")
sleep(2);
markEnd("doubleEnd")
> 2
sleep(2);
markEnd("doubleEnd")
> 4
getMarks()
> { "doubleEnd": [ { "t": 1305712151745, "dur": 4 } ] }

*Advantages over current draft*

1. To get the all data, analytics scripts only need to call one method
(getMarks) rather than two (getMarks+getMeasures).

2. Previously measures weren't strongly tied to marks so a timeline couldn't
be reconstructed without knowledge of the page.

Consider the old case:
mark("foo");
mark("foo");
measure("bar", "foo");
getMarks();
> { "foo": [1305712151745, 1305712151747] }
getMeasures();
> { "bar": [1] }

Based only on the getMarks+getMeasures data, the "bar" measure cannot be
placed on a timeline because it isn't known which "foo" it is associated
with (or even that it is associated with "foo" at all).

Now the new case:
mark("foo");
mark("foo");
markEnd("foo");
getMarks();
> { "sleep3": [ { "t": 1305712151745 }, { "t": 1305712151747, "dur": 1 } ] }

The getMarks() data now allows complete reconstruction of the timeline.

3. There is no ambiguity about clearing marks vs clearing measures.

Consider the old case:
mark("foo")
measure("bar", "foo")
clearMarks("foo")
// At this point, it may be unclear to the user what getMeasures() should
return. Since bar is based on foo and foo was cleared: does that mean bar is
now associated with fetchStart or has it been cleared or is it still
associated with foo even though foo is gone? I believe we intend the 3rd,
but I'm not sure that would be obvious to users.

4. Simpler to use as there is only one verb "mark" and fewer methods to
understand. Each method now takes just one argument that is the same across
all methods. Previously, it wasn't at all obvious what to pass to measure()
and in what order without looking it up.

Thoughts?

-Tony

Received on Wednesday, 18 May 2011 11:45:36 UTC