New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Compressed ServerTiming #17

Merged
merged 7 commits into from Aug 30, 2017

Conversation

Projects
None yet
2 participants
@cvazac
Copy link
Contributor

cvazac commented Aug 22, 2017

Server-timing entries are included on resource- and navigation-timing entries as serverTiming. They must have a name, might have a non-empty description, and will likely have a non-zero duration. This compression is build on the presumption that resources will have server timing entries with unique durations pointing mostly to the same name and descriptions. There are two parts to this compression:

  1. a data structure containing all of the unique name and description pairs (an array of arrays)
  2. for each resource timing entry, a list of duration and index pairs, where duration is the duration of the server timing entry and the index identifies the name and description in 1)

For example, when:
resource1 has 2 entries: m1=value1;desc1, m2=value2;desc3
resource2 has 2 entries: m1=value3;desc1, m1=value4;desc2
-on the beacon, we will send a servertiming of: [[m1, desc1, desc2], [m2, desc3]], as there are three unique "pairs" of metric and description: m1/desc1, m1/desc2, and m2/desc3
-in the compressed resource timing data for resource1, we will add: value1:0.0 (value=value1, entryIndex=0, descriptionIndex=0) and value2:1.0 (value=value2, entryIndex=1, descriptionIndex=0)
In the compressed resource timing data for resource2, we will add: value3:0.0 (value=value3, entryIndex=0, descriptionIndex=0) and value4:0.1 (value=value4, entryIndex=0, descriptionIndex=1).

To save bytes, we will omit the zeroes, and irrelevant separators. So:
value:1.0 becomes value:1
value:0.1 becomes value:.1
value:0.0 becomes value

And last, if there is only one description for a given metric and it is === '', then we omit that array entry:
[["description1", ""]] becomes [["description1"]]

To test:
navigate to:
https://soundcloud.com/

performance.getEntries().filter(e => e.serverTiming && e.serverTiming.length).reduce(function(arr, {serverTiming}) { arr = arr.concat(serverTiming); return arr; }, [])

return three entries:

[
  {name: "geoip", duration: 0.002274549, description: "geoip/geoip"}, 
  {name: "experiments", duration: 0.004756578, description: "api-v2/experiments"}, 
  {name: "geoip", duration: 0.001746519, description: "geoip/geoip"}
]

BOOMR.plugins.ResourceTiming.getCompressedResourceTiming().servertiming
equals: [["geoip", "geoip/geoip"], ["experiments", "api-v2/experiments"]
(Note: that "geoip" is before "experiments")

As it turns out, all three server timing entries are on the navigation timing entry (base page), so step into the trie like this:
BOOMR.plugins.ResourceTiming.getCompressedResourceTiming().restiming["https://"]['s']['oundcloud.com/']
you get back:
6,ay,aq,6v,6v,5o,4n,4n,f*1d4p,fm*30.002274549,0.004756578:1,0.001746519

In there you will find your three server timing entries.
Isolate the right dimension data: *30.002274549,0.004756578:1,0.001746519
lop off the *3 to get: 0.002274549,0.004756578:1,0.001746519

split at the comma:
entry one: 0.002274549 (correlates to "geoip" / "geoip/geoip")
entry two: 0.004756578:1 (correlates to "experiments" / "api-v2/experiments")
entry three: 0.001746519 (correlates to "geoip" / "geoip/geoip")

@nicjansma

This comment has been minimized.

Copy link
Owner

nicjansma commented Aug 23, 2017

Not sure why the ESLint rules didn't have indent already! Just added it. I noticed there was a lot of places with 2-spaces instead of 4.

@@ -788,6 +805,22 @@
data += SPECIAL_DATA_PREFIX + SPECIAL_DATA_SIZE_TYPE + compSize;
}

if (e.serverTiming.length) {

This comment has been minimized.

@nicjansma

nicjansma Aug 23, 2017

Owner

We should probably add a check for serverTiming's being defined first.

@nicjansma

This comment has been minimized.

Copy link
Owner

nicjansma commented Aug 23, 2017

One thing I'm not sure how to handle is breaking compatibility with the previous return values for things like getResourceTiming(), etc.

Should we add an optional parameter to getResourceTiming() to return in the new { restiming, servertiming} format?

Or should we make a semver change to 1.x and call it a breaking change?

@@ -746,6 +754,57 @@
return o;
};

/**
* @param {array} lookup server timing entries lookup

This comment has been minimized.

@nicjansma

nicjansma Aug 23, 2017

Owner

Short description too? And for decompressServerTiming

* @param {string} prefix URL prefix for the current node
*
* @returns {ResourceTiming[]} ResourceTiming array
*/
ResourceTimingDecompression.decompressResources = function(rt, prefix) {
ResourceTimingDecompression.decompressResources = function(rt, st, prefix) {

This comment has been minimized.

@nicjansma

nicjansma Aug 23, 2017

Owner

Would prefer to add new parameters as the last one, in case anyone is using the existing decompressResources API.

This comment has been minimized.

@cvazac

cvazac Aug 23, 2017

Author Contributor

I believe that prefix is only passed in from the recursive call, but it's up to you.

@nicjansma

This comment has been minimized.

Copy link
Owner

nicjansma commented Aug 23, 2017

One more thing, can you add a section to the README describing ServerTiming support and briefly how it's compressed? (something similar to this PR description is great)

cvazac added some commits Aug 23, 2017

@cvazac cvazac force-pushed the cvazac:cvazac/server-timing branch from 9444df2 to eee50d2 Aug 23, 2017

cvazac added some commits Aug 23, 2017

@cvazac

This comment has been minimized.

Copy link
Contributor Author

cvazac commented Aug 23, 2017

if you don't want to make it as a breaking change, you could pass in an optional out param to getResourceTiming. getResourceTiming will still only return the rt-data. if out is supplied, we can stick servertiming lookup on it

@nicjansma nicjansma changed the title compressed server timing Compressed ServerTiming Aug 29, 2017

@nicjansma

This comment has been minimized.

Copy link
Owner

nicjansma commented Aug 30, 2017

After looking at publicly published packages depending on this one (zero), I'm OK with breaking the return value at this point. I'll bump the semver.

@nicjansma nicjansma merged commit fbdb291 into nicjansma:master Aug 30, 2017

1 check passed

continuous-integration/travis-ci/pr The Travis CI build passed
Details
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment