blob: e2675b1f19ccbd7ddd99f7ff96c6ff7d71f8d184 [file] [log] [blame]
Chris Craikb122baf2015-03-05 13:58:42 -08001<!DOCTYPE html>
2<!--
3Copyright (c) 2013 The Chromium Authors. All rights reserved.
4Use of this source code is governed by a BSD-style license that can be
5found in the LICENSE file.
6-->
7<link rel="import" href="/base/base.html">
8<link rel="import" href="/core/auditor.html">
Chris Craik19832152015-04-16 15:43:38 -07009<link rel="import" href="/core/trace_model/event_info.html">
Chris Craikb122baf2015-03-05 13:58:42 -080010<link rel="import" href="/extras/audits/utils.html">
11<link rel="import" href="/extras/audits/chrome_model_helper.html">
Chris Craik44c28202015-05-12 17:25:16 -070012<link rel="import" href="/extras/audits/rail_ir_finder.html">
Chris Craikb122baf2015-03-05 13:58:42 -080013
14<script>
15'use strict';
16
17/**
18 * @fileoverview Base class for trace data Auditors.
19 */
20tv.exportTo('tv.e.audits', function() {
21 var Auditor = tv.c.Auditor;
22
23 /**
24 * Auditor for Chrome-specific traces.
25 * @constructor
26 */
27 function ChromeAuditor(model) {
28 this.model = model;
29 if (tv.e.audits.ChromeModelHelper.supportsModel(this.model)) {
30 var modelHelper = new tv.e.audits.ChromeModelHelper(this.model);
31
32 // Must be a browser in order to do audits.
33 if (modelHelper.browser === undefined)
34 this.modelHelper = undefined;
35 else
36 this.modelHelper = modelHelper;
37 } else {
38 this.modelHelper = undefined;
39 }
40 };
41
42 ChromeAuditor.prototype = {
43 __proto__: Auditor.prototype,
44
Chris Craik19832152015-04-16 15:43:38 -070045 runAnnotate: function() {
46 if (!this.modelHelper)
47 return;
48
49 this.model.getAllProcesses().forEach(function(process) {
50 if (process.labels !== undefined &&
51 process.labels.length == 1 &&
52 process.labels[0] == 'chrome://tracing')
53 process.important = false;
54 });
55 },
56
Chris Craikb122baf2015-03-05 13:58:42 -080057 runAudit: function() {
58 if (!this.modelHelper)
59 return;
60
61 // ChromeAuditor is disabled when used directly inside about://tracing,
62 // for now.
63 if (window.profilingView)
64 return;
65
66 var allLoadAndNetEvents = this.getAllLoadAndNetEvents();
67 var allFrameEvents = this.getAllFrameEvents();
68 var allLatencyEvents = this.getAllLatencyEvents();
69 var allFrameAndLatencyEvents = [];
70 allFrameAndLatencyEvents.push.apply(allFrameAndLatencyEvents,
71 allFrameEvents);
72 allFrameAndLatencyEvents.push.apply(allFrameAndLatencyEvents,
73 allLatencyEvents);
74
75 function mergeEventsIntoIR(title, colorId, events) {
76 var e0 = events[0];
77 var eN = events[events.length - 1];
78 var ir = new tv.c.trace_model.InteractionRecord(
79 title, colorId,
80 e0.start, eN.end - e0.start);
81 ir.events = events;
82 return ir;
83 }
84
85 var addIRs = function(records) {
86 records.forEach(function(ir) {
87 this.model.addInteractionRecord(ir);
88 }, this);
89 }.bind(this);
90
91 var mergedLoadIRs = tv.e.audits.mergeEvents(
92 allLoadAndNetEvents, 300,
93 mergeEventsIntoIR.bind(
94 undefined, 'Loading/Net',
95 tv.b.ui.getColorIdForGeneralPurposeString('mt_loading')));
96 addIRs(mergedLoadIRs);
97
98 var mergedFrameIRs = tv.e.audits.mergeEvents(
99 allFrameEvents, 150,
100 mergeEventsIntoIR.bind(
101 undefined, 'Rendering',
102 tv.b.ui.getColorIdForGeneralPurposeString('mt_rendering')));
103 addIRs(mergedFrameIRs);
104
Chris Craik44c28202015-05-12 17:25:16 -0700105 if (tv.e.audits.RAILIRFinder.supportsModelHelper(this.modelHelper)) {
106 var rirf = new tv.e.audits.RAILIRFinder(this.model, this.modelHelper);
107 var railIRs = rirf.findAllInteractionRecords();
108 addIRs(railIRs);
109 }
Chris Craikb122baf2015-03-05 13:58:42 -0800110
111 this.addBigTaskAlerts();
112 },
113
114 addBigTaskAlerts: function() {
115 var model = this.model;
116 tv.b.iterItems(this.modelHelper.renderers, function(pid, renderer) {
117 var slices = renderer.mainThread.sliceGroup.slices;
118 slices.forEach(function(slice) {
119 if (slice.category != 'toplevel')
120 return;
121 if (slice.duration > 75.0) {
Chris Craik19832152015-04-16 15:43:38 -0700122 var alertInfo = new tv.c.trace_model.EventInfo(
Chris Craikb122baf2015-03-05 13:58:42 -0800123 'Task too long',
124 'Tasks taking >= 75ms are bad, and should be broken up to' +
Chris Craik19832152015-04-16 15:43:38 -0700125 'ensure the main thread is responsive');
Chris Craikb122baf2015-03-05 13:58:42 -0800126 var center = slice.start + 0.5 * slice.duration;
127 var alert = new tv.c.trace_model.Alert(
Chris Craik19832152015-04-16 15:43:38 -0700128 alertInfo, center, [slice]);
Chris Craikb122baf2015-03-05 13:58:42 -0800129 model.alerts.push(alert);
130 }
131 });
132 });
133 },
134
135 getAllLoadAndNetEvents: function() {
136 var model = this.model;
137 if (this.modelHelper.browser === undefined)
138 return;
139 var browser = this.modelHelper.browser;
140
141 var events = [];
142 events.push.apply(
143 events, browser.getLoadingEventsInRange(model.bounds));
144 events.push.apply(
145 events, browser.getAllNetworkEventsInRange(model.bounds));
146 return events;
147 },
148
149 getAllFrameEvents: function() {
150 var model = this.model;
151 var frameEvents = [];
152 if (this.modelHelper.browser) {
153 var fe = this.modelHelper.browser.getFrameEventsInRange(
154 tv.e.audits.IMPL_FRAMETIME_TYPE,
155 model.bounds);
156 frameEvents.push.apply(frameEvents, fe);
157 }
158 tv.b.iterItems(this.modelHelper.renderers, function(pid, renderer) {
159 var fe = renderer.getFrameEventsInRange(tv.e.audits.IMPL_FRAMETIME_TYPE,
160 model.bounds);
161 frameEvents.push.apply(frameEvents, fe);
162 }, this);
163 frameEvents.sort(function(x, y) { return x.start - y.start; });
164 return frameEvents;
165 },
166
167 getAllLatencyEvents: function() {
168 if (!this.modelHelper.browser)
169 return [];
170 return this.modelHelper.browser.getLatencyEventsInRange(
171 this.model.bounds);
172 }
173 };
174
175 Auditor.register(ChromeAuditor);
176
177 return {
178 ChromeAuditor: ChromeAuditor
179 };
180});
181</script>