Skip to content
This repository has been archived by the owner on Jan 17, 2023. It is now read-only.

Fix #3673, instrument response times in shot creation flow #3727

Merged
merged 5 commits into from
Nov 15, 2017

Conversation

jaredhirsch
Copy link
Member

The metrics docs changes cover the basic overview.

The iframe unhide events seem to fire slightly before the UI is updated, but given how horrifyingly slow some of the steps are (especially full-page previews & downloads), I suspect these start and end points will be good enough for a while.

Easiest way to test this is to filter on 'perf' in the browser console, then run through various shot creation + download/upload flows:

screen shot 2017-11-06 at 4 22 07 pm

} else if (msg.funcName === "incrementUploadCount") {
Services.telemetry.scalarAdd('screenshots.upload', 1);
sendReply({type: "success", value: true});
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The changes in this file are the patch from #3726

@jaredhirsch
Copy link
Member Author

It occurred to me in the shower this morning that it might be nicer to keep the times inside the uicontrol state object, rather than overload sendEvent to turn it into a quasi-messaging broker with the internal-only events and separate time tracking. Might be something to fix in a refactoring bug later?

@jaredhirsch jaredhirsch requested a review from ianb November 8, 2017 17:11
@ghost
Copy link

ghost commented Nov 8, 2017

This is important to land for our OKR :)

@ghost ghost added the perf Performance-related label Nov 8, 2017
Copy link
Contributor

@ianb ianb left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The matching approach seems reasonable, and I like that it uses our existing events for most moments in time. However, I don't think we should submit these as normal events. Google Analytics has a system specifically for these timings: https://github.com/peaksandpies/universal-analytics#user-timing-tracking

We'd have to reintroduce the server /timing endpoint (it was removed in #3254 – it might have been slightly broken at the time), and then add a sendTiming function instead of overloading sendEvent.

@jaredhirsch
Copy link
Member Author

@ianb cool, restored /timing (slightly modified) and updated the addon code accordingly. R?

@jaredhirsch jaredhirsch requested a review from ianb November 9, 2017 00:29
let matched = false;
filters.forEach(filter => {
matched = matched || match(filter, action, label);
});
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nitpick: since we are only interested in the first matching filter, we can use array.find() here.

userTimingLabel: bodyObj.timingLabel
};
userAnalytics.timing(params).send();
simpleResponse(res, "OK", 200);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Previously /timing allowed batching. That would make the code on the addon side a little more complicated though. Perhaps keep the completed timing data in one object and the in progress ones in another, so whenever teh in progress list is empty and there are completed timing measurements, send those to /timing?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, I noticed that too. Since sendEvent fires many more pings, and fires each one individually, it didn't seem worth bothering with the extra state management.

If there's a good reason to batch events in general, maybe we can adjust both endpoints in a followup bug?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I made a followup in #3757

@chenba
Copy link
Collaborator

chenba commented Nov 9, 2017

👍 :shipit:

@ianb ianb mentioned this pull request Nov 13, 2017
Copy link
Contributor

@ianb ianb left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Several comments

let timingCategory = "addon";
let url = main.getBackend() + "/timing";
let req = new XMLHttpRequest();
req.open("POST", url);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should probably start using fetch() (though I also keep falling back to XHR too ;)

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

sure, already filed as #2261

exc.status = req.status;
exc.statusText = req.statusText;
console.error(exc);
// TODO: send the error to sentry, maybe?
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should reject a promise. Also it should create a promise! Same as sendEvent. I'm not sure how consistently we watch the sendEvent promise, arguably we should have a wrapped version of these functions for the not-uncommon case where we want to send-and-forget (with catcher.watchFunction(sendTiming, true))

@@ -446,6 +448,7 @@ this.ui = (function() { // eslint-disable-line no-unused-vars

unhide() {
this.element.style.display = "";
catcher.watchPromise(callBackground("sendEvent", "internal", "unhide-preview-frame"));
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm a little concerned that callBackground is going to confound the timing measurements a little. But... eh?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, the time to send a message seems pretty small, <=10ms (for short messages), and some of these steps take several seconds, so it seemed fine for now.

docs/METRICS.md Outdated

Internal-only events are used to measure the time from user input to user-visible UI response.

*NOTE: Internal-only events are not submitted to GA.*
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Probably these don't even need to be documented, but... well, no harm.

docs/METRICS.md Outdated

##### First step: starting the shot

1. [x] Time from clicking the page action (or toolbar button) to displaying the preselection iframe, `addon/perf-response-time/page-action` with `cd1: {ms response time}`
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think these need to be adjusted to reflect they aren't events, but timings.

Copy link
Contributor

@ianb ianb left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One note, which you could resolve or not, eh. Otherwise 👍 – want to squash and merge?

let req = new XMLHttpRequest();
req.open("POST", url);
req.setRequestHeader("content-type", "application/json");
req.onload = catcher.watchFunction(() => {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Technically I don't think this will reject the promise, if there's an exception in the function then the promise will just hang. But it will report something to Sentry.

@jaredhirsch jaredhirsch merged commit 82cb4b7 into master Nov 15, 2017
@jaredhirsch jaredhirsch deleted the shot-creation-response-times branch November 15, 2017 16:43
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
perf Performance-related
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants