Skip to content

Commit

Permalink
[RPP Observations] Add throttling settings to landing page
Browse files Browse the repository at this point in the history
This CL adds 2 new components for selecting CPU and network throttling.
They are meant to be web component versions of the toolbar throttling
selectors.

https://screenshot.googleplex.com/8QCkWHpu9sUT9Yj

Bug: 311440438
Change-Id: Ie53a153acbdf3289b8386f42c7ded6adaac8ef0b
Reviewed-on: https://chromium-review.googlesource.com/c/devtools/devtools-frontend/+/5673433
Reviewed-by: Jack Franklin <jacktfranklin@chromium.org>
Reviewed-by: Nancy Li <nancyly@chromium.org>
Commit-Queue: Adam Raine <asraine@chromium.org>
  • Loading branch information
Adam Raine authored and Devtools-frontend LUCI CQ committed Jul 8, 2024
1 parent 1690af9 commit a2155b7
Show file tree
Hide file tree
Showing 9 changed files with 522 additions and 0 deletions.
2 changes: 2 additions & 0 deletions config/gni/devtools_grd_files.gni
Original file line number Diff line number Diff line change
Expand Up @@ -1726,11 +1726,13 @@ grd_files_debug_sources = [
"front_end/panels/timeline/UIDevtoolsUtils.js",
"front_end/panels/timeline/components/Breadcrumbs.js",
"front_end/panels/timeline/components/BreadcrumbsUI.js",
"front_end/panels/timeline/components/CPUThrottlingSelector.js",
"front_end/panels/timeline/components/DetailsView.js",
"front_end/panels/timeline/components/EntryLabelOverlay.js",
"front_end/panels/timeline/components/InteractionBreakdown.js",
"front_end/panels/timeline/components/LiveMetricsView.js",
"front_end/panels/timeline/components/NetworkRequestTooltip.js",
"front_end/panels/timeline/components/NetworkThrottlingSelector.js",
"front_end/panels/timeline/components/Sidebar.js",
"front_end/panels/timeline/components/SidebarAnnotationsTab.js",
"front_end/panels/timeline/components/SidebarInsight.js",
Expand Down
5 changes: 5 additions & 0 deletions front_end/panels/timeline/components/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -26,11 +26,13 @@ devtools_module("components") {
sources = [
"Breadcrumbs.ts",
"BreadcrumbsUI.ts",
"CPUThrottlingSelector.ts",
"DetailsView.ts",
"EntryLabelOverlay.ts",
"InteractionBreakdown.ts",
"LiveMetricsView.ts",
"NetworkRequestTooltip.ts",
"NetworkThrottlingSelector.ts",
"Sidebar.ts",
"SidebarAnnotationsTab.ts",
"SidebarInsight.ts",
Expand All @@ -55,6 +57,7 @@ devtools_module("components") {
"../../../ui/legacy/components/perf_ui:bundle",
"../../../ui/lit-html:bundle",
"../../../ui/visual_logging:bundle",
"../../mobile_throttling:bundle",
]
}

Expand All @@ -79,9 +82,11 @@ ts_library("unittests") {

sources = [
"BreadcrumbsUI.test.ts",
"CPUThrottlingSelector.test.ts",
"InteractionBreakdown.test.ts",
"Invalidations.test.ts",
"LiveMetricsView.test.ts",
"NetworkThrottlingSelector.test.ts",
"SidebarAnnotationsTab.test.ts",
"SidebarInsight.test.ts",
]
Expand Down
81 changes: 81 additions & 0 deletions front_end/panels/timeline/components/CPUThrottlingSelector.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
// Copyright 2024 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

import * as SDK from '../../../core/sdk/sdk.js';
import {renderElementIntoDOM} from '../../../testing/DOMHelpers.js';
import {describeWithEnvironment} from '../../../testing/EnvironmentHelpers.js';
import type * as Menus from '../../../ui/components/menus/menus.js';
import * as Coordinator from '../../../ui/components/render_coordinator/render_coordinator.js';

import * as Components from './components.js';

describeWithEnvironment('CPUThrottlingSelector', () => {
const coordinator = Coordinator.RenderCoordinator.RenderCoordinator.instance();
let cpuThrottlingManager: SDK.CPUThrottlingManager.CPUThrottlingManager;

beforeEach(() => {
cpuThrottlingManager = SDK.CPUThrottlingManager.CPUThrottlingManager.instance({forceNew: true});
});

it('renders all CPU throttling presets', async () => {
const view = new Components.CPUThrottlingSelector.CPUThrottlingSelector();
renderElementIntoDOM(view);

await coordinator.done();

const menuItems = view.shadowRoot!.querySelectorAll('devtools-menu-item') as NodeListOf<Menus.Menu.MenuItem>;

assert.lengthOf(menuItems, 4);

assert.strictEqual(menuItems[0].value, 1);
assert.isTrue(menuItems[0].selected);
assert.match(menuItems[0].innerText, /No throttling/);

assert.strictEqual(menuItems[1].value, 4);
assert.isFalse(menuItems[1].selected);
assert.match(menuItems[1].innerText, /4× slowdown/);

assert.strictEqual(menuItems[2].value, 6);
assert.isFalse(menuItems[2].selected);
assert.match(menuItems[2].innerText, /6× slowdown/);

assert.strictEqual(menuItems[3].value, 20);
assert.isFalse(menuItems[3].selected);
assert.match(menuItems[3].innerText, /20× slowdown/);
});

it('updates CPU throttling manager on change', async () => {
const view = new Components.CPUThrottlingSelector.CPUThrottlingSelector();
renderElementIntoDOM(view);

await coordinator.done();

const menuItems = view.shadowRoot!.querySelectorAll('devtools-menu-item') as NodeListOf<Menus.Menu.MenuItem>;

assert.isTrue(menuItems[0].selected);
assert.strictEqual(cpuThrottlingManager.cpuThrottlingRate(), 1);

menuItems[1].click();
await coordinator.done();

assert.isTrue(menuItems[1].selected);
assert.strictEqual(cpuThrottlingManager.cpuThrottlingRate(), 4);
});

it('reacts to changes in CPU throttling manager', async () => {
const view = new Components.CPUThrottlingSelector.CPUThrottlingSelector();
renderElementIntoDOM(view);

await coordinator.done();

const menuItems = view.shadowRoot!.querySelectorAll('devtools-menu-item') as NodeListOf<Menus.Menu.MenuItem>;

assert.isTrue(menuItems[0].selected);

cpuThrottlingManager.setCPUThrottlingRate(6);
await coordinator.done();

assert.isTrue(menuItems[2].selected);
});
});
96 changes: 96 additions & 0 deletions front_end/panels/timeline/components/CPUThrottlingSelector.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
// Copyright 2024 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

import * as i18n from '../../../core/i18n/i18n.js';
import * as SDK from '../../../core/sdk/sdk.js';
import * as ComponentHelpers from '../../../ui/components/helpers/helpers.js';
import * as Menus from '../../../ui/components/menus/menus.js';
import * as LitHtml from '../../../ui/lit-html/lit-html.js';
import * as MobileThrottling from '../../mobile_throttling/mobile_throttling.js';

const {html} = LitHtml;

const UIStrings = {
/**
* @description Text label for a menu item indicating that no throttling is applied.
*/
noThrottling: 'No throttling',
/**
* @description Text label for a menu item indicating that a specific slowdown multiplier is applied.
* @example {2} PH1
*/
dSlowdown: '{PH1}× slowdown',
};

const str_ = i18n.i18n.registerUIStrings('panels/timeline/components/CPUThrottlingSelector.ts', UIStrings);
const i18nString = i18n.i18n.getLocalizedString.bind(undefined, str_);

export class CPUThrottlingSelector extends HTMLElement {
static readonly litTagName = LitHtml.literal`devtools-cpu-throttling-selector`;
readonly #shadow = this.attachShadow({mode: 'open'});

#currentRate: number;

constructor() {
super();
this.#currentRate = SDK.CPUThrottlingManager.CPUThrottlingManager.instance().cpuThrottlingRate();
this.#render();
}

connectedCallback(): void {
SDK.CPUThrottlingManager.CPUThrottlingManager.instance().addEventListener(
SDK.CPUThrottlingManager.Events.RateChanged, this.#onRateChange, this);
}

disconnectedCallback(): void {
SDK.CPUThrottlingManager.CPUThrottlingManager.instance().removeEventListener(
SDK.CPUThrottlingManager.Events.RateChanged, this.#onRateChange, this);
}

#onRateChange(event: {data: SDK.CPUThrottlingManager.EventTypes['RateChanged']}): void {
this.#currentRate = event.data;
void ComponentHelpers.ScheduledRender.scheduleRender(this, this.#render);
}

#onMenuItemSelected(event: Menus.SelectMenu.SelectMenuItemSelectedEvent): void {
MobileThrottling.ThrottlingManager.throttlingManager().setCPUThrottlingRate(Number(event.itemValue));
}

#render = (): void => {
// clang-format off
const output = html`
<${Menus.SelectMenu.SelectMenu.litTagName}
@selectmenuselected=${this.#onMenuItemSelected}
.showDivider=${true}
.showArrow=${true}
.sideButton=${false}
.showSelectedItem=${true}
.showConnector=${false}
.buttonTitle=${this.#currentRate === 1 ? i18nString(UIStrings.noThrottling) : i18nString(UIStrings.dSlowdown, {PH1: this.#currentRate})}
>
${MobileThrottling.ThrottlingPresets.ThrottlingPresets.cpuThrottlingPresets.map(rate => {
const title = rate === 1 ? i18nString(UIStrings.noThrottling) : i18nString(UIStrings.dSlowdown, {PH1: rate});
return LitHtml.html`
<${Menus.Menu.MenuItem.litTagName}
.value=${rate}
.selected=${this.#currentRate === rate}
>
${title}
</${Menus.Menu.MenuItem.litTagName}>
`;
})}
</${Menus.SelectMenu.SelectMenu.litTagName}>
`;
// clang-format on
LitHtml.render(output, this.#shadow, {host: this});
};
}

customElements.define('devtools-cpu-throttling-selector', CPUThrottlingSelector);

declare global {
interface HTMLElementTagNameMap {
'devtools-cpu-throttling-selector': CPUThrottlingSelector;
}
}
15 changes: 15 additions & 0 deletions front_end/panels/timeline/components/LiveMetricsView.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,9 @@ import * as Settings from '../../../ui/components/settings/settings.js';
import * as UI from '../../../ui/legacy/legacy.js';
import * as LitHtml from '../../../ui/lit-html/lit-html.js';

import {CPUThrottlingSelector} from './CPUThrottlingSelector.js';
import liveMetricsViewStyles from './liveMetricsView.css.js';
import {NetworkThrottlingSelector} from './NetworkThrottlingSelector.js';

const {html, nothing, Directives} = LitHtml;
const {until} = Directives;
Expand Down Expand Up @@ -257,6 +259,16 @@ export class LiveMetricsView extends HTMLElement {
// clang-format on
}

#renderThrottlingSettings(): LitHtml.LitTemplate {
return html`
<div class="card-title">Throttling</div>
<span class="throttling-setting">CPU: <${CPUThrottlingSelector.litTagName}></${
CPUThrottlingSelector.litTagName}></span>
<span class="throttling-setting">Network: <${NetworkThrottlingSelector.litTagName}></${
NetworkThrottlingSelector.litTagName}></span>
`;
}

#render = (): void => {
const automaticSetting = CrUXManager.CrUXManager.instance().getAutomaticSetting();

Expand Down Expand Up @@ -302,6 +314,9 @@ export class LiveMetricsView extends HTMLElement {
{setting: automaticSetting} as Settings.SettingCheckbox.SettingCheckboxData}>
</${Settings.SettingCheckbox.SettingCheckbox.litTagName}>
</div>
<div id="throttling" class="card">
${this.#renderThrottlingSettings()}
</div>
<div id="record" class="card">
${this.#renderRecordAction(this.#toggleRecordAction)}
</div>
Expand Down
Loading

0 comments on commit a2155b7

Please sign in to comment.