Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(779)

Unified Diff: tracing/tracing/metrics/system_health/first_paint_metric.html

Issue 1963583005: Rewrite firstPaintMetric to support extracting multiple navigations from a single trace (Closed) Base URL: https://chromium.googlesource.com/external/github.com/catapult-project/catapult.git@master
Patch Set: Created 4 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: tracing/tracing/metrics/system_health/first_paint_metric.html
diff --git a/tracing/tracing/metrics/system_health/first_paint_metric.html b/tracing/tracing/metrics/system_health/first_paint_metric.html
index bbbcc22f14ecd72c49ebc7e8457a08a98cbea1af..a39b843abc46dc1d534e4e8c84b71e804cfb0646 100644
--- a/tracing/tracing/metrics/system_health/first_paint_metric.html
+++ b/tracing/tracing/metrics/system_health/first_paint_metric.html
@@ -19,10 +19,7 @@ tr.exportTo('tr.metrics.sh', function() {
var timeDurationInMs_smallerIsBetter =
tr.v.Unit.byName.timeDurationInMs_smallerIsBetter;
- function findTargetRendererHelper(model) {
- var chromeHelper = model.getOrCreateHelper(
- tr.model.helpers.ChromeModelHelper);
-
+ function findTargetRendererHelper(chromeHelper) {
var largestPid = -1;
for (var pid in chromeHelper.rendererHelpers) {
var rendererHelper = chromeHelper.rendererHelpers[pid];
@@ -38,63 +35,122 @@ tr.exportTo('tr.metrics.sh', function() {
return chromeHelper.rendererHelpers[largestPid];
}
- function findNavigationStartEvent(rendererHelper) {
- var navigationStartEvent = undefined;
-
+ function navigationStartFinder(rendererHelper) {
+ var navigationStartsForFrameId = {};
rendererHelper.mainThread.sliceGroup.iterateAllEventsInThisContainer(
() => true, function(ev) {
- if (navigationStartEvent !== undefined ||
- ev.category !== 'blink.user_timing')
+ if (ev.category !== 'blink.user_timing' ||
+ ev.title !== 'navigationStart')
return;
- if (ev.title === 'navigationStart')
- navigationStartEvent = ev;
+
+ var frameIdRef = ev.args['frame'];
+ var list = navigationStartsForFrameId[frameIdRef];
+ if (list === undefined) {
+ navigationStartsForFrameId[frameIdRef] = list = [];
+ }
+ list.unshift(ev);
},
this);
- return navigationStartEvent;
+ return function findNavigationStartEventForFrameBeforeTimestamp(frameIdRef,
+ ts) {
+ var list = navigationStartsForFrameId[frameIdRef];
+ if (list === undefined)
+ throw new Error('No navigationStartEvent found for frame id "' +
+ frameIdRef + '"');
+
+ var eventBeforeTimestamp;
+ list.forEach(function(ev) {
+ if (ev.start > ts)
+ return;
+
+ if (eventBeforeTimestamp === undefined)
+ eventBeforeTimestamp = ev;
+ }, this);
+ if (eventBeforeTimestamp === undefined)
+ throw new Error('Failed to find navigationStartEvent.');
+ return eventBeforeTimestamp;
+ }
+ }
+
+ function findUrlOfFrameAt(rendererHelper, frameIdRef, ts) {
+ var url;
+
+ var objects = rendererHelper.process.objects;
+ var frameLoaderInstances = objects.instancesByTypeName_['FrameLoader'];
+ frameLoaderInstances.forEach(function(instance) {
+ var snapshot = instance.getSnapshotAt(ts);
+ if (frameIdRef !== snapshot.args['frame']['id_ref'])
+ return;
+
+ url = snapshot.args['documentLoaderURL'];
+ }, this);
+
+ return url;
}
- function findFirstPaintEvent(rendererHelper, title, frame) {
- var firstPaintEvent = undefined;
+ function findFirstPaintEvents(rendererHelper, title) {
+ var firstPaintEvents = [];
rendererHelper.process.iterateAllEvents(
function(ev) {
- if (firstPaintEvent !== undefined ||
- ev.category !== 'blink.user_timing' ||
- ev.title !== title ||
- ev.args === undefined || ev.args['frame'] !== frame)
+ if (ev.category !== 'blink.user_timing' ||
+ ev.title !== title)
return;
- firstPaintEvent = ev;
+ firstPaintEvents.push(ev);
}, this);
- return firstPaintEvent;
+ return firstPaintEvents;
+ }
+
+ function prepareTelemetryInternalEventPredicate(rendererHelper) {
+ var ignoreRegionSlices = [];
+ rendererHelper.mainThread.asyncSliceGroup.iterateAllEventsInThisContainer(
+ () => true, function(slice) {
+ if (slice.title.match(/^telemetry\.internal/))
+ ignoreRegionSlices.push(slice);
+ }, this);
+
+ return function isTelemetryInternalEvent(slice) {
+ for (var i = 0; i < ignoreRegionSlices.length; ++ i) {
+ if (ignoreRegionSlices[i].bounds(slice))
+ return true;
+ }
+ return false;
+ }
}
function firstPaintMetric(valueList, model) {
- var rendererHelper = findTargetRendererHelper(model);
- var navigationStartEvent = findNavigationStartEvent(rendererHelper);
-
- if (navigationStartEvent === undefined)
- throw new Error('Failed to find navigationStartEvent.');
-
- var frame = navigationStartEvent.args['frame'];
- var firstContentfulPaintEvent = findFirstPaintEvent(rendererHelper,
- 'firstContentfulPaint', frame);
- if (firstContentfulPaintEvent === undefined)
- throw new Error(
- 'Failed to find firstContentfulPaintEvent for frame ' + frame);
-
- var grouping_keys = {};
-
- var timeToFirstContentfulPaint =
- firstContentfulPaintEvent.start - navigationStartEvent.start;
- valueList.addValue(new tr.v.NumericValue(
- model.canonicalUrlThatCreatedThisTrace, 'firstContentfulPaint',
- new tr.v.ScalarNumeric(timeDurationInMs_smallerIsBetter,
- timeToFirstContentfulPaint),
- { description: 'time to first contentful paint' },
- grouping_keys));
+ var chromeHelper = model.getOrCreateHelper(
+ tr.model.helpers.ChromeModelHelper);
+ var rendererHelper = findTargetRendererHelper(chromeHelper);
+ var isTelemetryInternalEvent =
+ prepareTelemetryInternalEventPredicate(rendererHelper);
+ var findNavigationStartEventForFrameBeforeTimestamp =
+ navigationStartFinder(rendererHelper);
+
+ var firstPaintEvents = findFirstPaintEvents(rendererHelper,
+ 'firstContentfulPaint');
+ firstPaintEvents = firstPaintEvents.filter(
+ (ev) => !isTelemetryInternalEvent(ev));
+ firstPaintEvents.forEach(function(ev) {
+ var frameIdRef = ev.args['frame'];
+ var url = findUrlOfFrameAt(rendererHelper, frameIdRef, ev.start);
+ var navigationStartEvent =
+ findNavigationStartEventForFrameBeforeTimestamp(frameIdRef, ev.start);
+
+ var timeToFirstContentfulPaint =
+ ev.start - navigationStartEvent.start;
+
+ var grouping_keys = {url: url};
+ valueList.addValue(new tr.v.NumericValue(
benjhayden 2016/05/10 19:54:46 Instead of several scalars, do you want to use a N
kouhei (in TOK) 2016/05/11 06:39:33 I think we want separate individual values, as his
nednguyen 2016/05/11 21:36:38 Why do you think the histogram doesn't make sense?
kouhei (in TOK) 2016/05/12 05:41:25 Added Numeric histogram, but not sure how we can u
nednguyen 2016/05/12 15:35:30 For future use cases of Pcv2, I can imagine we hav
+ model.canonicalUrlThatCreatedThisTrace, 'firstContentfulPaint',
benjhayden 2016/05/10 20:25:43 This is spelled "model.canonicalUrl" now.
kouhei (in TOK) 2016/05/11 06:39:33 Done.
+ new tr.v.ScalarNumeric(timeDurationInMs_smallerIsBetter,
+ timeToFirstContentfulPaint),
+ { description: 'time to first contentful paint' },
+ grouping_keys));
+ }, this);
}
firstPaintMetric.prototype = {
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698