| OLD | NEW |
| (Empty) | |
| 1 <!DOCTYPE html> |
| 2 <!-- |
| 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 |
| 5 found in the LICENSE file. |
| 6 --> |
| 7 |
| 8 <link rel="import" href="/tracing/base/category_util.html"> |
| 9 <link rel="import" href="/tracing/base/math/statistics.html"> |
| 10 <link rel="import" href="/tracing/metrics/metric_registry.html"> |
| 11 <link rel="import" href="/tracing/metrics/system_health/utils.html"> |
| 12 <link rel="import" href="/tracing/model/helpers/chrome_model_helper.html"> |
| 13 <link rel="import" href="/tracing/model/timed_event.html"> |
| 14 <link rel="import" href="/tracing/value/histogram.html"> |
| 15 |
| 16 <script> |
| 17 'use strict'; |
| 18 |
| 19 tr.exportTo('tr.metrics.sh', function() { |
| 20 const timeDurationInMs_smallerIsBetter = |
| 21 tr.b.Unit.byName.timeDurationInMs_smallerIsBetter; |
| 22 |
| 23 function createHistogram(name, boundaries) { |
| 24 const histogram = new tr.v.Histogram(name, |
| 25 timeDurationInMs_smallerIsBetter, bound
aries); |
| 26 histogram.customizeSummaryOptions({ |
| 27 avg: true, |
| 28 count: true, |
| 29 max: true, |
| 30 min: true, |
| 31 std: true, |
| 32 sum: true, |
| 33 }); |
| 34 return histogram; |
| 35 } |
| 36 |
| 37 function candidatesEvents(rendererHelper) { |
| 38 const events = []; |
| 39 for (const ev of rendererHelper.process.getDescendantEvents()) { |
| 40 if (rendererHelper.isTelemetryInternalEvent(ev)) |
| 41 continue; |
| 42 events.push(ev); |
| 43 } |
| 44 return events; |
| 45 } |
| 46 |
| 47 function collectSamples(events, eventName, condition) { |
| 48 const samples = []; |
| 49 for (const ev of events) { |
| 50 if ((!condition && ev.title === eventName) || (condition && condition(ev))
) { |
| 51 const timeToEvent = ev.end - ev.start; |
| 52 // console.log(ev); |
| 53 samples.push({ |
| 54 value: timeToEvent, |
| 55 diagnostics: {} |
| 56 }); |
| 57 } |
| 58 } |
| 59 return samples; |
| 60 } |
| 61 |
| 62 function addSamplesToHistogram(samples, histogram) { |
| 63 for (const sample of samples) |
| 64 histogram.addSample(sample.value, sample.diagnostics); |
| 65 } |
| 66 |
| 67 function addHistogram(histogramName, boundaries, eventName) { |
| 68 const histogram = createHistogram(histogramName, boundareis); |
| 69 histogram.description = histogramName; |
| 70 } |
| 71 |
| 72 const DEFAULT_BOUNDARIES = tr.v.HistogramBinBoundaries |
| 73 .createLinear(0, 0.05, 10) |
| 74 .addExponentialBins(20e3, 20); |
| 75 |
| 76 class WebComponentsHistogram { |
| 77 constructor({name, eventName, |
| 78 boundaries = DEFAULT_BOUNDARIES, |
| 79 condition }) { |
| 80 this.histogram = createHistogram(name, boundaries); |
| 81 // TODO: We do not need eventName if condition is given. |
| 82 this.eventName = eventName || name; |
| 83 this.histogram.description = name; |
| 84 this.condition = condition; |
| 85 } |
| 86 } |
| 87 |
| 88 // Memo: ev: |
| 89 // ev.args: TRACE_EVENT's args |
| 90 // ev.args: { name: 'x-thing' } |
| 91 // ev.title: "CustomElementReactionQueue::invokeReactions" |
| 92 // ev.ancestorAndSubsequentSlices: Array: [p-ev, pp-ev, ppp-ev, ,,,,,] |
| 93 // ev.parentSlice: Ev: p-ev |
| 94 |
| 95 function isDescendantEventOf(ev, f) { |
| 96 if (!ev.ancestorAndSubsequentSlices) |
| 97 return false; |
| 98 for (const parentEv of ev.ancestorAndSubsequentSlices) { |
| 99 if (f(parentEv)) |
| 100 return true; |
| 101 } |
| 102 return false; |
| 103 } |
| 104 |
| 105 const invokeRectionsEventName = 'CustomElementReactionQueue::InvokeReactions'; |
| 106 const connectedEventName = 'CustomElementConnectedCallbackReaction::Invoke'; |
| 107 |
| 108 function isXApp(ev) { |
| 109 return ev.title === invokeRectionsEventName && ev.args && ev.args['name'] ==
= 'x-app'; |
| 110 } |
| 111 |
| 112 function isXItem(ev) { |
| 113 return ev.title === invokeRectionsEventName && ev.args && ev.args['name'] ==
= 'x-item'; |
| 114 } |
| 115 |
| 116 function isXThing(ev) { |
| 117 return ev.title === invokeRectionsEventName && ev.args && ev.args['name'] ==
= 'x-thing'; |
| 118 } |
| 119 |
| 120 function isXAppConnected(ev) { |
| 121 return ev.title === connectedEventName && ev.args && ev.args['name'] === 'x-
app'; |
| 122 } |
| 123 |
| 124 function isXItemConnected(ev) { |
| 125 return ev.title === connectedEventName && ev.args && ev.args['name'] === 'x-
item'; |
| 126 } |
| 127 |
| 128 function isXThingConnected(ev) { |
| 129 return ev.title === connectedEventName && ev.args && ev.args['name'] === 'x-
thing'; |
| 130 } |
| 131 |
| 132 function isProcessStylesheetUnderXThing(ev) { |
| 133 return ev.title === 'StyleElement::ProcessStyleSheet' && isDescendantEventOf
(ev, isXThing) |
| 134 } |
| 135 |
| 136 function webComponentsMetric(values, model) { |
| 137 const groups = [ |
| 138 new WebComponentsHistogram({ name: 'Node::UpdateDistribution' }), |
| 139 new WebComponentsHistogram({ name: 'UpdateLayoutTree' }), |
| 140 new WebComponentsHistogram({ name: 'Document::UpdateStyle' }), |
| 141 new WebComponentsHistogram({ name: 'CustomElementRegistry::define' }), |
| 142 |
| 143 new WebComponentsHistogram({ name: 'CE::invokeReactions_x-app', |
| 144 eventName: invokeRectionsEventName, |
| 145 condition: isXApp}), |
| 146 new WebComponentsHistogram({ name: 'CE::invokeReactions_x-item', |
| 147 eventName: invokeRectionsEventName, |
| 148 condition: isXItem}), |
| 149 new WebComponentsHistogram({ name: 'CE::invokeReactions_x-thing', |
| 150 eventName: invokeRectionsEventName, |
| 151 condition: isXThing}), |
| 152 |
| 153 new WebComponentsHistogram({ name: 'CE::connected_x-xpp', |
| 154 eventName: connectedEventName, |
| 155 condition: isXAppConnected}), |
| 156 new WebComponentsHistogram({ name: 'CE::connected_x-item', |
| 157 eventName: connectedEventName, |
| 158 condition: isXItemConnected}), |
| 159 new WebComponentsHistogram({ name: 'CE::connected_x-thing', |
| 160 eventName: connectedEventName, |
| 161 condition: isXThingConnected}), |
| 162 |
| 163 new WebComponentsHistogram({ name: 'StyleElement::ProcessStyleSheet' }), |
| 164 new WebComponentsHistogram({ name: 'StyleElement::ProcessStyleSheet_under_
x-thing', |
| 165 eventName: 'StyleElement::ProcessStyleSheet', |
| 166 condition: isProcessStylesheetUnderXThing }), |
| 167 |
| 168 new WebComponentsHistogram({ name: 'StyleElement::Process' }), |
| 169 new WebComponentsHistogram({ name: 'StyleElement::CreateSheet' }), |
| 170 new WebComponentsHistogram({ name: 'StyleEngine::CreateSheet' }), |
| 171 new WebComponentsHistogram({ name: 'StyleEngine::CreateInline' }), |
| 172 |
| 173 new WebComponentsHistogram({ name: 'StyleSheetContents::CheckLoaded' }), |
| 174 |
| 175 new WebComponentsHistogram({ name: 'FrameView::performLayout' }), |
| 176 |
| 177 // new WebComponentsHistogram({ name: 'EventPath::initialize' }), |
| 178 // new WebComponentsHistogram({ name: 'EventPath::calculatePath' }), |
| 179 // new WebComponentsHistogram({ name: 'EventPath::calculateTreeOrderAndSet
NearestAncestorClosedTree' }), |
| 180 // new WebComponentsHistogram({ name: 'EventPath::calculateAdjustedTargets
' }), |
| 181 // new WebComponentsHistogram({ name: 'EventPath::adjustForRelatedTarget'
}), |
| 182 ]; |
| 183 const chromeHelper = model.getOrCreateHelper( |
| 184 tr.model.helpers.ChromeModelHelper); |
| 185 for (const pid in chromeHelper.rendererHelpers) { |
| 186 const rendererHelper = chromeHelper.rendererHelpers[pid]; |
| 187 if (rendererHelper.isChromeTracingUI) |
| 188 continue; |
| 189 |
| 190 const events = candidatesEvents(rendererHelper); |
| 191 for (const group of groups) { |
| 192 addSamplesToHistogram(collectSamples(events, group.eventName, group.cond
ition), |
| 193 group.histogram); |
| 194 } |
| 195 } |
| 196 for (const group of groups) { |
| 197 values.addHistogram(group.histogram); |
| 198 } |
| 199 } |
| 200 |
| 201 tr.metrics.MetricRegistry.register(webComponentsMetric); |
| 202 |
| 203 return { |
| 204 webComponentsMetric, |
| 205 }; |
| 206 }); |
| 207 </script> |
| OLD | NEW |