| // Copyright 2017 The Chromium Authors |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| import type * as ProtocolProxyApi from '../../generated/protocol-proxy-api.js'; |
| import * as Platform from '../platform/platform.js'; |
| |
| import {SDKModel} from './SDKModel.js'; |
| import {Capability, type Target} from './Target.js'; |
| |
| export class PerformanceMetricsModel extends SDKModel<void> { |
| readonly #agent: ProtocolProxyApi.PerformanceApi; |
| readonly #metricModes = new Map<string, MetricMode>([ |
| ['TaskDuration', MetricMode.CUMULATIVE_TIME], |
| ['ScriptDuration', MetricMode.CUMULATIVE_TIME], |
| ['LayoutDuration', MetricMode.CUMULATIVE_TIME], |
| ['RecalcStyleDuration', MetricMode.CUMULATIVE_TIME], |
| ['LayoutCount', MetricMode.CUMULATIVE_COUNT], |
| ['RecalcStyleCount', MetricMode.CUMULATIVE_COUNT], |
| ]); |
| readonly #metricData = new Map<string, { |
| lastValue: (number | undefined), |
| lastTimestamp: (number|undefined), |
| }>(); |
| |
| constructor(target: Target) { |
| super(target); |
| this.#agent = target.performanceAgent(); |
| } |
| |
| enable(): Promise<Object> { |
| return this.#agent.invoke_enable({}); |
| } |
| |
| disable(): Promise<Object> { |
| return this.#agent.invoke_disable(); |
| } |
| |
| async requestMetrics(): Promise<{ |
| metrics: Map<string, number>, |
| timestamp: number, |
| }> { |
| const rawMetrics = await this.#agent.invoke_getMetrics() || []; |
| const metrics = new Map<string, number>(); |
| const timestamp = performance.now(); |
| for (const metric of rawMetrics.metrics) { |
| let data = this.#metricData.get(metric.name); |
| if (!data) { |
| data = {lastValue: undefined, lastTimestamp: undefined}; |
| this.#metricData.set(metric.name, data); |
| } |
| let value; |
| switch (this.#metricModes.get(metric.name)) { |
| case MetricMode.CUMULATIVE_TIME: |
| value = (data.lastTimestamp && data.lastValue) ? |
| Platform.NumberUtilities.clamp( |
| (metric.value - data.lastValue) * 1000 / (timestamp - data.lastTimestamp), 0, 1) : |
| 0; |
| data.lastValue = metric.value; |
| data.lastTimestamp = timestamp; |
| break; |
| case MetricMode.CUMULATIVE_COUNT: |
| value = (data.lastTimestamp && data.lastValue) ? |
| 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, timestamp}; |
| } |
| } |
| |
| const enum MetricMode { |
| CUMULATIVE_TIME = 'CumulativeTime', |
| CUMULATIVE_COUNT = 'CumulativeCount', |
| } |
| |
| SDKModel.register(PerformanceMetricsModel, {capabilities: Capability.DOM, autostart: false}); |