Commit 848031b9 authored by Dmitry Gozman's avatar Dmitry Gozman Committed by Commit Bot

[DevTools] Move performance metrics processing to the model

This will make it easier to support multiple models in PerformanceMonitor.

Bug: none
Change-Id: I7ea678fba1e4f634cd26ef05638cac2a8ec3414b
Reviewed-on: https://chromium-review.googlesource.com/953713Reviewed-by: default avatarPavel Feldman <pfeldman@chromium.org>
Commit-Queue: Dmitry Gozman <dgozman@chromium.org>
Cr-Commit-Position: refs/heads/master@{#541695}
parent 3fcd47cf
...@@ -9,6 +9,17 @@ SDK.PerformanceMetricsModel = class extends SDK.SDKModel { ...@@ -9,6 +9,17 @@ SDK.PerformanceMetricsModel = class extends SDK.SDKModel {
constructor(target) { constructor(target) {
super(target); super(target);
this._agent = target.performanceAgent(); this._agent = target.performanceAgent();
const mode = SDK.PerformanceMetricsModel.MetricMode;
/** @type {!Map<string, !SDK.PerformanceMetricsModel.MetricMode>} */
this._metricModes = new Map([
['TaskDuration', mode.CumulativeTime], ['ScriptDuration', mode.CumulativeTime],
['LayoutDuration', mode.CumulativeTime], ['RecalcStyleDuration', mode.CumulativeTime],
['LayoutCount', mode.CumulativeCount], ['RecalcStyleCount', mode.CumulativeCount]
]);
/** @type {!Map<string, !{lastValue: (number|undefined), lastTimestamp: (number|undefined)}>} */
this._metricData = new Map();
} }
/** /**
...@@ -26,11 +37,48 @@ SDK.PerformanceMetricsModel = class extends SDK.SDKModel { ...@@ -26,11 +37,48 @@ SDK.PerformanceMetricsModel = class extends SDK.SDKModel {
} }
/** /**
* @return {!Promise<!Array<!Protocol.Performance.Metric>>} * @return {!Promise<!{metrics: !Map<string, number>, timestamp: number}>}
*/ */
async requestMetrics() { async requestMetrics() {
return await this._agent.getMetrics() || []; const rawMetrics = await this._agent.getMetrics() || [];
const metrics = new Map();
const timestamp = performance.now();
for (const metric of rawMetrics) {
let data = this._metricData.get(metric.name);
if (!data) {
data = {};
this._metricData.set(metric.name, data);
}
let value;
switch (this._metricModes.get(metric.name)) {
case SDK.PerformanceMetricsModel.MetricMode.CumulativeTime:
value = data.lastTimestamp ?
Number.constrain((metric.value - data.lastValue) * 1000 / (timestamp - data.lastTimestamp), 0, 1) :
0;
data.lastValue = metric.value;
data.lastTimestamp = timestamp;
break;
case SDK.PerformanceMetricsModel.MetricMode.CumulativeCount:
value = data.lastTimestamp ?
Math.max(0, (metric.value - data.lastValue) * 1000 / (timestamp - data.lastTimestamp)) :
0;
data.lastValue = metric.value;
data.lastTimestamp = timestamp;
break;
default:
value = metric.value;
break;
}
metrics.set(metric.name, value);
}
return {metrics: metrics, timestamp: timestamp};
} }
}; };
/** @enum {symbol} */
SDK.PerformanceMetricsModel.MetricMode = {
CumulativeTime: Symbol('CumulativeTime'),
CumulativeCount: Symbol('CumulativeCount'),
};
SDK.SDKModel.register(SDK.PerformanceMetricsModel, SDK.Target.Capability.Browser, false); SDK.SDKModel.register(SDK.PerformanceMetricsModel, SDK.Target.Capability.Browser, false);
...@@ -27,16 +27,6 @@ Timeline.PerformanceMonitor = class extends UI.HBox { ...@@ -27,16 +27,6 @@ Timeline.PerformanceMonitor = class extends UI.HBox {
this._canvas = /** @type {!HTMLCanvasElement} */ (chartContainer.createChild('canvas')); this._canvas = /** @type {!HTMLCanvasElement} */ (chartContainer.createChild('canvas'));
this.contentElement.createChild('div', 'perfmon-chart-suspend-overlay fill').createChild('div').textContent = this.contentElement.createChild('div', 'perfmon-chart-suspend-overlay fill').createChild('div').textContent =
Common.UIString('Paused'); Common.UIString('Paused');
const mode = Timeline.PerformanceMonitor.MetricMode;
/** @type {!Map<string, !Timeline.PerformanceMonitor.MetricMode>} */
this._metricModes = new Map([
['TaskDuration', mode.CumulativeTime], ['ScriptDuration', mode.CumulativeTime],
['LayoutDuration', mode.CumulativeTime], ['RecalcStyleDuration', mode.CumulativeTime],
['LayoutCount', mode.CumulativeCount], ['RecalcStyleCount', mode.CumulativeCount]
]);
/** @type {!Map<string, !{lastValue: (number|undefined), lastTimestamp: (number|undefined)}>} */
this._metricData = new Map();
this._controlPane.addEventListener( this._controlPane.addEventListener(
Timeline.PerformanceMonitor.ControlPane.Events.MetricChanged, this._recalcChartHeight, this); Timeline.PerformanceMonitor.ControlPane.Events.MetricChanged, this._recalcChartHeight, this);
} }
...@@ -91,44 +81,9 @@ Timeline.PerformanceMonitor = class extends UI.HBox { ...@@ -91,44 +81,9 @@ Timeline.PerformanceMonitor = class extends UI.HBox {
} }
async _poll() { async _poll() {
const metrics = await this._model.requestMetrics(); const data = await this._model.requestMetrics();
this._processMetrics(metrics); const timestamp = data.timestamp;
} const metrics = data.metrics;
/**
* @param {!Array<!Protocol.Performance.Metric>} rawMetrics
*/
_processMetrics(rawMetrics) {
const metrics = new Map();
const timestamp = performance.now();
for (const metric of rawMetrics) {
let data = this._metricData.get(metric.name);
if (!data) {
data = {};
this._metricData.set(metric.name, data);
}
let value;
switch (this._metricModes.get(metric.name)) {
case Timeline.PerformanceMonitor.MetricMode.CumulativeTime:
value = data.lastTimestamp ?
Number.constrain((metric.value - data.lastValue) * 1000 / (timestamp - data.lastTimestamp), 0, 1) :
0;
data.lastValue = metric.value;
data.lastTimestamp = timestamp;
break;
case Timeline.PerformanceMonitor.MetricMode.CumulativeCount:
value = data.lastTimestamp ?
Math.max(0, (metric.value - data.lastValue) * 1000 / (timestamp - data.lastTimestamp)) :
0;
data.lastValue = metric.value;
data.lastTimestamp = timestamp;
break;
default:
value = metric.value;
break;
}
metrics.set(metric.name, value);
}
this._metricsBuffer.push({timestamp, metrics: metrics}); this._metricsBuffer.push({timestamp, metrics: metrics});
const millisPerWidth = this._width / this._pixelsPerMs; const millisPerWidth = this._width / this._pixelsPerMs;
// Multiply by 2 as the pollInterval has some jitter and to have some extra samples if window is resized. // Multiply by 2 as the pollInterval has some jitter and to have some extra samples if window is resized.
...@@ -377,12 +332,6 @@ Timeline.PerformanceMonitor = class extends UI.HBox { ...@@ -377,12 +332,6 @@ Timeline.PerformanceMonitor = class extends UI.HBox {
} }
}; };
/** @enum {symbol} */
Timeline.PerformanceMonitor.MetricMode = {
CumulativeTime: Symbol('CumulativeTime'),
CumulativeCount: Symbol('CumulativeCount'),
};
/** @enum {symbol} */ /** @enum {symbol} */
Timeline.PerformanceMonitor.Format = { Timeline.PerformanceMonitor.Format = {
Percent: Symbol('Percent'), Percent: Symbol('Percent'),
...@@ -404,8 +353,7 @@ Timeline.PerformanceMonitor.ChartInfo; ...@@ -404,8 +353,7 @@ Timeline.PerformanceMonitor.ChartInfo;
/** /**
* @typedef {!{ * @typedef {!{
* name: string, * name: string,
* color: string, * color: string
* mode: (!Timeline.PerformanceMonitor.MetricMode|undefined)
* }} * }}
*/ */
Timeline.PerformanceMonitor.MetricInfo; Timeline.PerformanceMonitor.MetricInfo;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment