OLD | NEW |
---|---|
1 <!DOCTYPE html> | 1 <!DOCTYPE html> |
2 <!-- | 2 <!-- |
3 Copyright 2017 The Chromium Authors. All rights reserved. | 3 Copyright 2017 The Chromium Authors. All rights reserved. |
4 Use of this source code is governed by a BSD-style license that can be | 4 Use of this source code is governed by a BSD-style license that can be |
5 found in the LICENSE file. | 5 found in the LICENSE file. |
6 --> | 6 --> |
7 | 7 |
8 <link rel="import" href="/tracing/base/iteration_helpers.html"> | 8 <link rel="import" href="/tracing/base/iteration_helpers.html"> |
9 <link rel="import" href="/tracing/extras/chrome/estimated_input_latency.html"> | 9 <link rel="import" href="/tracing/extras/chrome/estimated_input_latency.html"> |
10 <link rel="import" href="/tracing/model/helpers/chrome_model_helper.html"> | 10 <link rel="import" href="/tracing/model/helpers/chrome_model_helper.html"> |
(...skipping 25 matching lines...) Expand all Loading... | |
36 * Returns true if the slice contains a forced GC event. Some stories force | 36 * Returns true if the slice contains a forced GC event. Some stories force |
37 * garbage collection before sampling memory usage. Since a forced GC takes | 37 * garbage collection before sampling memory usage. Since a forced GC takes |
38 * long time we need to ignore it to avoid biasing the input latency results. | 38 * long time we need to ignore it to avoid biasing the input latency results. |
39 */ | 39 */ |
40 function containsForcedGC_(slice) { | 40 function containsForcedGC_(slice) { |
41 return slice.findTopmostSlicesRelativeToThisSlice( | 41 return slice.findTopmostSlicesRelativeToThisSlice( |
42 tr.metrics.v8.utils.isForcedGarbageCollectionEvent).length > 0; | 42 tr.metrics.v8.utils.isForcedGarbageCollectionEvent).length > 0; |
43 } | 43 } |
44 | 44 |
45 /** | 45 /** |
46 * Returns the time window during which the the page is interactive. | 46 * Returns a histogram for EQT with the given name and description. |
benjhayden
2017/02/17 19:33:30
You can change this to an @returns tag like
@retur
ulan
2017/02/17 19:46:22
Done.
| |
47 * This time window excludes the page load time. We compute EQT only for | 47 * @param {string} name Name of the histogram. |
48 * the interactive time because the input latency during the page load time | 48 * @param {string} description Description of the histogram. |
49 * is not interesting. | |
50 * @throws if there is no interactive time window or if there are multiple | |
51 * interactive time windows. | |
52 */ | 49 */ |
53 function getInteractiveWindow_(model, rendererHelper) { | 50 function createHistogramForEQT_(name, description) { |
54 let interactiveTimestamp = tr.b.getOnlyElement( | 51 let histogram = new tr.v.Histogram(name, |
55 tr.e.chrome.getInteractiveTimestamps(model).get(rendererHelper.pid)); | 52 tr.b.Unit.byName.timeDurationInMs_smallerIsBetter, EQT_BOUNDARIES); |
56 return tr.b.Range.fromExplicitRange(interactiveTimestamp, Infinity) | 53 histogram.customizeSummaryOptions({ |
57 .findIntersection(rendererHelper.mainThread.bounds); | 54 avg: false, |
55 count: false, | |
56 max: true, | |
57 min: false, | |
58 std: false, | |
59 sum: false, | |
60 }); | |
61 histogram.description = description; | |
62 return histogram; | |
58 } | 63 } |
59 | 64 |
60 /** | 65 /** |
61 * Adds the input latency estimated as the maximum expected queueing time | 66 * Adds the input latency estimated as the maximum expected queueing time |
62 * in the sliding time window of size WINDOW_SIZE_MS. | 67 * in the sliding time window of size WINDOW_SIZE_MS. |
63 * The result histogram contains value per renderer. | 68 * The result histogram contains value per renderer. |
64 */ | 69 */ |
65 function estimatedInputLatency(values, model) { | 70 function estimatedInputLatency(values, model) { |
66 let chromeHelper = model.getOrCreateHelper( | 71 let chromeHelper = model.getOrCreateHelper( |
67 tr.model.helpers.ChromeModelHelper); | 72 tr.model.helpers.ChromeModelHelper); |
68 let histogram = new tr.v.Histogram( | 73 let totalHistogram = createHistogramForEQT_( |
74 `total:${WINDOW_SIZE_MS}ms_window:renderer_eqt`, | |
75 `The maximum EQT in a ${WINDOW_SIZE_MS}ms sliding window` + | |
76 ' for a given renderer'); | |
77 let interactiveHistogram = createHistogramForEQT_( | |
69 `interactive:${WINDOW_SIZE_MS}ms_window:renderer_eqt`, | 78 `interactive:${WINDOW_SIZE_MS}ms_window:renderer_eqt`, |
70 tr.b.Unit.byName.timeDurationInMs_smallerIsBetter, | |
71 EQT_BOUNDARIES); | |
72 histogram.customizeSummaryOptions({ | |
73 avg: false, | |
74 count: false, | |
75 max: true, | |
76 min: false, | |
77 std: false, | |
78 sum: false, | |
79 }); | |
80 histogram.description = | |
81 `The maximum EQT in a ${WINDOW_SIZE_MS}ms sliding window` + | 79 `The maximum EQT in a ${WINDOW_SIZE_MS}ms sliding window` + |
82 ' for a given renderer'; | 80 ' for a given renderer while the page is interactive'); |
83 let rendererHelpers = tr.b.dictionaryValues(chromeHelper.rendererHelpers); | 81 let rendererHelpers = tr.b.dictionaryValues(chromeHelper.rendererHelpers); |
84 for (let rendererHelper of rendererHelpers) { | 82 for (let rendererHelper of rendererHelpers) { |
85 if (rendererHelper.isChromeTracingUI) continue; | 83 if (rendererHelper.isChromeTracingUI) continue; |
86 let tasks = rendererHelper.mainThread.sliceGroup.topLevelSlices | 84 let tasks = rendererHelper.mainThread.sliceGroup.topLevelSlices |
87 .filter(slice => slice.duration > 0 && !containsForcedGC_(slice)) | 85 .filter(slice => slice.duration > 0 && !containsForcedGC_(slice)) |
88 .map(slice => {return {start: slice.start, end: slice.end};}); | 86 .map(slice => {return {start: slice.start, end: slice.end};}); |
89 let interactiveWindow = getInteractiveWindow_(model, rendererHelper); | 87 totalHistogram.addSample( |
90 histogram.addSample(tr.e.chrome.maxExpectedQueueingTimeInSlidingWindow( | 88 tr.e.chrome.maxExpectedQueueingTimeInSlidingWindow( |
benjhayden
2017/02/17 19:33:30
If most callers of this function pass a Range.min
ulan
2017/02/17 19:46:22
Thanks, will change in a followup.
| |
91 interactiveWindow.min, interactiveWindow.max, | 89 rendererHelper.mainThread.bounds.min, |
92 WINDOW_SIZE_MS, tasks)); | 90 rendererHelper.mainThread.bounds.max, |
91 WINDOW_SIZE_MS, tasks)); | |
92 let interactiveTimestamps = | |
93 tr.e.chrome.getInteractiveTimestamps(model).get(rendererHelper.pid); | |
94 if (interactiveTimestamps.length === 0) continue; | |
95 if (interactiveTimestamps.length > 1) { | |
96 // TODO(ulan): Support multiple interactive time windows when | |
97 // https://crbug.com/692112 is fixed. | |
98 continue; | |
99 } | |
100 let interactiveWindow = | |
101 tr.b.Range.fromExplicitRange(interactiveTimestamps[0], Infinity) | |
102 .findIntersection(rendererHelper.mainThread.bounds); | |
103 interactiveHistogram.addSample( | |
104 tr.e.chrome.maxExpectedQueueingTimeInSlidingWindow( | |
105 interactiveWindow.min, interactiveWindow.max, | |
106 WINDOW_SIZE_MS, tasks)); | |
93 } | 107 } |
94 values.addHistogram(histogram); | 108 values.addHistogram(totalHistogram); |
109 values.addHistogram(interactiveHistogram); | |
95 } | 110 } |
96 | 111 |
97 tr.metrics.MetricRegistry.register(estimatedInputLatency); | 112 tr.metrics.MetricRegistry.register(estimatedInputLatency); |
benjhayden
2017/02/17 19:33:30
Can you add "Metric" to the end of the metric name
ulan
2017/02/17 19:46:22
Yep, my another CL already does it. I will land it
| |
98 | 113 |
99 return { | 114 return { |
100 estimatedInputLatency, | 115 estimatedInputLatency, |
101 }; | 116 }; |
102 }); | 117 }); |
103 </script> | 118 </script> |
OLD | NEW |